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 2020/05/09 14:47:26 UTC

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

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

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


The following commit(s) were added to refs/heads/asf-site by this push:
     new d1cf6a9  Published site at 2774510e2bd70968a76a9f77df51ce987453aeba.
d1cf6a9 is described below

commit d1cf6a9a254906ca685fe1d10ac22b1fad7300da
Author: jenkins <bu...@apache.org>
AuthorDate: Sat May 9 14:46:36 2020 +0000

    Published site at 2774510e2bd70968a76a9f77df51ce987453aeba.
---
 acid-semantics.html                                |   2 +-
 apache_hbase_reference_guide.pdf                   |   4 +-
 book.html                                          |   2 +-
 bulk-loads.html                                    |   2 +-
 checkstyle-aggregate.html                          |  12 +-
 coc.html                                           |   2 +-
 dependencies.html                                  |   2 +-
 dependency-convergence.html                        |   2 +-
 dependency-info.html                               |   2 +-
 dependency-management.html                         |   2 +-
 devapidocs/constant-values.html                    |   4 +-
 .../hadoop/hbase/master/MetaFixer.Either.html      |  20 +-
 .../org/apache/hadoop/hbase/master/MetaFixer.html  |  34 +-
 .../src-html/org/apache/hadoop/hbase/Version.html  |   4 +-
 .../hadoop/hbase/master/MetaFixer.Either.html      | 679 +++++++++++----------
 .../org/apache/hadoop/hbase/master/MetaFixer.html  | 679 +++++++++++----------
 downloads.html                                     |   2 +-
 export_control.html                                |   2 +-
 index.html                                         |   2 +-
 issue-tracking.html                                |   2 +-
 mail-lists.html                                    |   2 +-
 metrics.html                                       |   2 +-
 old_news.html                                      |   2 +-
 plugin-management.html                             |   2 +-
 plugins.html                                       |   2 +-
 poweredbyhbase.html                                |   2 +-
 project-info.html                                  |   2 +-
 project-reports.html                               |   2 +-
 project-summary.html                               |   2 +-
 pseudo-distributed.html                            |   2 +-
 replication.html                                   |   2 +-
 resources.html                                     |   2 +-
 source-repository.html                             |   2 +-
 sponsors.html                                      |   2 +-
 supportingprojects.html                            |   2 +-
 team-list.html                                     |   2 +-
 testdevapidocs/index-all.html                      |   4 +
 .../apache/hadoop/hbase/master/TestMetaFixer.html  |  68 ++-
 .../org/apache/hadoop/hbase/package-tree.html      |  12 +-
 .../hadoop/hbase/procedure/package-tree.html       |   8 +-
 .../hadoop/hbase/procedure2/package-tree.html      |   4 +-
 .../hadoop/hbase/regionserver/package-tree.html    |   4 +-
 .../org/apache/hadoop/hbase/test/package-tree.html |   2 +-
 .../org/apache/hadoop/hbase/wal/package-tree.html  |   4 +-
 .../apache/hadoop/hbase/master/TestMetaFixer.html  | 599 ++++++++++--------
 45 files changed, 1189 insertions(+), 1008 deletions(-)

diff --git a/acid-semantics.html b/acid-semantics.html
index 36b3b73..8fd1984 100644
--- a/acid-semantics.html
+++ b/acid-semantics.html
@@ -467,7 +467,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/apache_hbase_reference_guide.pdf b/apache_hbase_reference_guide.pdf
index c4eec1d..60ac052 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.rc.2, based on Prawn 2.2.2)
 /Producer (Apache HBase Team)
-/ModDate (D:20200508143156+00'00')
-/CreationDate (D:20200508144301+00'00')
+/ModDate (D:20200509143239+00'00')
+/CreationDate (D:20200509144340+00'00')
 >>
 endobj
 2 0 obj
diff --git a/book.html b/book.html
index f654d95..f835abb 100644
--- a/book.html
+++ b/book.html
@@ -45276,7 +45276,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 2020-05-08 14:31:56 UTC
+Last updated 2020-05-09 14:32:39 UTC
 </div>
 </div>
 <script type="text/x-mathjax-config">
diff --git a/bulk-loads.html b/bulk-loads.html
index fc9dae9..d1abe3d 100644
--- a/bulk-loads.html
+++ b/bulk-loads.html
@@ -172,7 +172,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/checkstyle-aggregate.html b/checkstyle-aggregate.html
index d9ad1ce..94121ae 100644
--- a/checkstyle-aggregate.html
+++ b/checkstyle-aggregate.html
@@ -7354,7 +7354,7 @@
 <tr class="b">
 <td>annotation</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_annotation.html#MissingDeprecated">MissingDeprecated</a></td>
-<td>9</td>
+<td>10</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
 <tr class="a">
 <td>blocks</td>
@@ -7453,7 +7453,7 @@
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_javadoc.html#JavadocTagContinuationIndentation">JavadocTagContinuationIndentation</a>
 <ul>
 <li>offset: <tt>&quot;2&quot;</tt></li></ul></td>
-<td>585</td>
+<td>584</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
 <tr class="a">
 <td></td>
@@ -8489,8 +8489,8 @@
 <td>600</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
-<td>javadoc</td>
-<td>JavadocTagContinuationIndentation</td>
+<td>annotation</td>
+<td>MissingDeprecated</td>
 <td>Javadoc comment at column 33 has parse error. Details: no viable alternative at input '&lt;Map.Entry&lt;' while parsing HTML_ELEMENT</td>
 <td>642</td></tr>
 <tr class="b">
@@ -42515,7 +42515,7 @@
 <td>imports</td>
 <td>ImportOrder</td>
 <td>Wrong order for 'org.apache.hadoop.hbase.master.assignment.GCMultipleMergedRegionsProcedure' import.</td>
-<td>38</td></tr></table></div>
+<td>40</td></tr></table></div>
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.master.TestMirroringTableStateManager.java">org/apache/hadoop/hbase/master/TestMirroringTableStateManager.java</h3>
 <table border="0" class="table table-striped">
@@ -79271,7 +79271,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/coc.html b/coc.html
index b8dc04c..6dd73d6 100644
--- a/coc.html
+++ b/coc.html
@@ -241,7 +241,7 @@ email to <a class="externalLink" href="mailto:private@hbase.apache.org">the priv
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/dependencies.html b/dependencies.html
index 1ca5d40..847bc79 100644
--- a/dependencies.html
+++ b/dependencies.html
@@ -313,7 +313,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/dependency-convergence.html b/dependency-convergence.html
index c68c301..cd1f87e 100644
--- a/dependency-convergence.html
+++ b/dependency-convergence.html
@@ -788,7 +788,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/dependency-info.html b/dependency-info.html
index 96c1190..6c500f8 100644
--- a/dependency-info.html
+++ b/dependency-info.html
@@ -194,7 +194,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/dependency-management.html b/dependency-management.html
index 1be578f..705b2ac 100644
--- a/dependency-management.html
+++ b/dependency-management.html
@@ -1068,7 +1068,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/devapidocs/constant-values.html b/devapidocs/constant-values.html
index de794a4..aa05f8c 100644
--- a/devapidocs/constant-values.html
+++ b/devapidocs/constant-values.html
@@ -4137,14 +4137,14 @@
 <!--   -->
 </a><code>public&nbsp;static&nbsp;final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
 <td><code><a href="org/apache/hadoop/hbase/Version.html#date">date</a></code></td>
-<td class="colLast"><code>"Fri May  8 14:39:16 UTC 2020"</code></td>
+<td class="colLast"><code>"Sat May  9 14:39:54 UTC 2020"</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>"0cd70ed89cbf7a77f7e53f09627ef7889eaca4ab"</code></td>
+<td class="colLast"><code>"2774510e2bd70968a76a9f77df51ce987453aeba"</code></td>
 </tr>
 <tr class="altColor">
 <td class="colFirst"><a name="org.apache.hadoop.hbase.Version.srcChecksum">
diff --git a/devapidocs/org/apache/hadoop/hbase/master/MetaFixer.Either.html b/devapidocs/org/apache/hadoop/hbase/master/MetaFixer.Either.html
index f4777a1..65c9811 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/MetaFixer.Either.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/MetaFixer.Either.html
@@ -113,7 +113,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private static class <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.312">MetaFixer.Either</a>&lt;L,R&gt;
+<pre>private static class <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.335">MetaFixer.Either</a>&lt;L,R&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">A union over <code>L</code> and <code>R</code>.</div>
 </li>
@@ -227,7 +227,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>left</h4>
-<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="type parameter in MetaFixer.Either">L</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.313">left</a></pre>
+<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="type parameter in MetaFixer.Either">L</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.336">left</a></pre>
 </li>
 </ul>
 <a name="right">
@@ -236,7 +236,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>right</h4>
-<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="type parameter in MetaFixer.Either">R</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.314">right</a></pre>
+<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="type parameter in MetaFixer.Either">R</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.337">right</a></pre>
 </li>
 </ul>
 </li>
@@ -255,7 +255,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>Either</h4>
-<pre><a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.324">Either</a>(<a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="type parameter in MetaFixer.Either">L</a>&nbsp;left,
+<pre><a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.347">Either</a>(<a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="type parameter in MetaFixer.Either">L</a>&nbsp;left,
        <a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="type parameter in MetaFixer.Either">R</a>&nbsp;right)</pre>
 </li>
 </ul>
@@ -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>ofLeft</h4>
-<pre>public static&nbsp;&lt;L,R&gt;&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="class in org.apache.hadoop.hbase.master">MetaFixer.Either</a>&lt;L,R&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.316">ofLeft</a>(L&nbsp;left)</pre>
+<pre>public static&nbsp;&lt;L,R&gt;&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="class in org.apache.hadoop.hbase.master">MetaFixer.Either</a>&lt;L,R&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.339">ofLeft</a>(L&nbsp;left)</pre>
 </li>
 </ul>
 <a name="ofRight-java.lang.Object-">
@@ -286,7 +286,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>ofRight</h4>
-<pre>public static&nbsp;&lt;L,R&gt;&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="class in org.apache.hadoop.hbase.master">MetaFixer.Either</a>&lt;L,R&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.320">ofRight</a>(R&nbsp;right)</pre>
+<pre>public static&nbsp;&lt;L,R&gt;&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="class in org.apache.hadoop.hbase.master">MetaFixer.Either</a>&lt;L,R&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.343">ofRight</a>(R&nbsp;right)</pre>
 </li>
 </ul>
 <a name="hasLeft--">
@@ -295,7 +295,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>hasLeft</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.329">hasLeft</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.352">hasLeft</a>()</pre>
 </li>
 </ul>
 <a name="getLeft--">
@@ -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>getLeft</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="type parameter in MetaFixer.Either">L</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.333">getLeft</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="type parameter in MetaFixer.Either">L</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.356">getLeft</a>()</pre>
 </li>
 </ul>
 <a name="hasRight--">
@@ -313,7 +313,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>hasRight</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.340">hasRight</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.363">hasRight</a>()</pre>
 </li>
 </ul>
 <a name="getRight--">
@@ -322,7 +322,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getRight</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="type parameter in MetaFixer.Either">R</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.344">getRight</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/MetaFixer.Either.html" title="type parameter in MetaFixer.Either">R</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html#line.367">getRight</a>()</pre>
 </li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/MetaFixer.html b/devapidocs/org/apache/hadoop/hbase/master/MetaFixer.html
index 429a521..3005b72 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/MetaFixer.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/MetaFixer.html
@@ -110,7 +110,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre>@InterfaceAudience.Private
-class <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.52">MetaFixer</a>
+class <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.53">MetaFixer</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">Server-side fixing of bad or inconsistent state in hbase:meta.
  Distinct from MetaTableAccessor because <a href="../../../../../org/apache/hadoop/hbase/MetaTableAccessor.html" title="class in org.apache.hadoop.hbase"><code>MetaTableAccessor</code></a> is about low-level
@@ -294,7 +294,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>LOG</h4>
-<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.53">LOG</a></pre>
+<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.54">LOG</a></pre>
 </li>
 </ul>
 <a name="MAX_MERGE_COUNT_KEY">
@@ -303,7 +303,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>MAX_MERGE_COUNT_KEY</h4>
-<pre>private static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.54">MAX_MERGE_COUNT_KEY</a></pre>
+<pre>private static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.55">MAX_MERGE_COUNT_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.master.MetaFixer.MAX_MERGE_COUNT_KEY">Constant Field Values</a></dd>
@@ -316,7 +316,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>MAX_MERGE_COUNT_DEFAULT</h4>
-<pre>private static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.55">MAX_MERGE_COUNT_DEFAULT</a></pre>
+<pre>private static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.56">MAX_MERGE_COUNT_DEFAULT</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.master.MetaFixer.MAX_MERGE_COUNT_DEFAULT">Constant Field Values</a></dd>
@@ -329,7 +329,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>masterServices</h4>
-<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.57">masterServices</a></pre>
+<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.58">masterServices</a></pre>
 </li>
 </ul>
 <a name="maxMergeCount">
@@ -338,7 +338,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>maxMergeCount</h4>
-<pre>private final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.61">maxMergeCount</a></pre>
+<pre>private final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.62">maxMergeCount</a></pre>
 <div class="block">Maximum for many regions to merge at a time.</div>
 </li>
 </ul>
@@ -356,7 +356,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>MetaFixer</h4>
-<pre><a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.63">MetaFixer</a>(<a href="../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;masterServices)</pre>
+<pre><a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.64">MetaFixer</a>(<a href="../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;masterServices)</pre>
 </li>
 </ul>
 </li>
@@ -373,7 +373,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>fix</h4>
-<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.69">fix</a>()
+<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.70">fix</a>()
   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -387,7 +387,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>fixHoles</h4>
-<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.87">fixHoles</a>(<a href="../../../../../org/apache/hadoop/hbase/master/CatalogJanitor.Report.html" title="class in org.apache.hadoop.hbase.master">CatalogJanitor.Report</a>&nbsp;report)</pre>
+<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.88">fixHoles</a>(<a href="../../../../../org/apache/hadoop/hbase/master/CatalogJanitor.Report.html" title="class in org.apache.hadoop.hbase.master">CatalogJanitor.Report</a>&nbsp;report)</pre>
 <div class="block">If hole, it papers it over by adding a region in the filesystem and to hbase:meta.
  Does not assign.</div>
 </li>
@@ -398,7 +398,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>createRegionInfosForHoles</h4>
-<pre>private static&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.111">createRegionInfosForHoles</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/uti [...]
+<pre>private static&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.112">createRegionInfosForHoles</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/uti [...]
 <div class="block">Create a new <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client"><code>RegionInfo</code></a> corresponding to each provided "hole" pair.</div>
 </li>
 </ul>
@@ -408,7 +408,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getHoleCover</h4>
-<pre>private static&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html?is-external=true" title="class or interface in java.util">Optional</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/MetaFixer.html#line.127">getHoleCover</a>(<a href="../../../../../org/apache/hadoop/hbase/util/Pair.html"  [...]
+<pre>private static&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html?is-external=true" title="class or interface in java.util">Optional</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/MetaFixer.html#line.128">getHoleCover</a>(<a href="../../../../../org/apache/hadoop/hbase/util/Pair.html"  [...]
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>Attempts to calculate a new <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client"><code>RegionInfo</code></a> that covers the region range described
@@ -422,7 +422,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>buildRegionInfo</h4>
-<pre>private static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.162">buildRegionInfo</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tn,
+<pre>private static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.163">buildRegionInfo</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tn,
                                           byte[]&nbsp;start,
                                           byte[]&nbsp;end)</pre>
 </li>
@@ -433,7 +433,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>createMetaEntries</h4>
-<pre>private static&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.173">createMetaEntries</a>(<a href="../../../../../org/apache/hadoop/hbase/master/MasterServic [...]
+<pre>private static&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.174">createMetaEntries</a>(<a href="../../../../../org/apache/hadoop/hbase/master/MasterServic [...]
                                                   <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;newRegionInfos)</pre>
 <div class="block">Create entries in the <code>hbase:meta</code> for each provided <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client"><code>RegionInfo</code></a>. Best effort.</div>
 <dl>
@@ -452,7 +452,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>fixOverlaps</h4>
-<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.217">fixOverlaps</a>(<a href="../../../../../org/apache/hadoop/hbase/master/CatalogJanitor.Report.html" title="class in org.apache.hadoop.hbase.master">CatalogJanitor.Report</a>&nbsp;report)
+<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.218">fixOverlaps</a>(<a href="../../../../../org/apache/hadoop/hbase/master/CatalogJanitor.Report.html" title="class in org.apache.hadoop.hbase.master">CatalogJanitor.Report</a>&nbsp;report)
           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">Fix overlaps noted in CJ consistency report.</div>
 <dl>
@@ -467,7 +467,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>calculateMerges</h4>
-<pre>static&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&gt;&nbsp;<a href="../../../../../src-htm [...]
+<pre>static&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&gt;&nbsp;<a href="../../../../../src-htm [...]
                                                    <a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/util/Pair.html" title="class in org.apache.hadoop.hbase.util">Pair</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="../../../../../org/apache/hado [...]
 <div class="block">Run through <code>overlaps</code> and return a list of merges to run.
  Presumes overlaps are ordered (which they are coming out of the CatalogJanitor
@@ -485,7 +485,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionInfoWithLargestEndKey</h4>
-<pre>static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.273">getRegionInfoWithLargestEndKey</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;a,
+<pre>static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.296">getRegionInfoWithLargestEndKey</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;a,
                                                  <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;b)</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -500,7 +500,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>isOverlap</h4>
-<pre>static&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.301">isOverlap</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri,
+<pre>static&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/MetaFixer.html#line.324">isOverlap</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri,
                          <a href="../../../../../org/apache/hadoop/hbase/util/Pair.html" title="class in org.apache.hadoop.hbase.util">Pair</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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;pair)</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/Version.html b/devapidocs/src-html/org/apache/hadoop/hbase/Version.html
index 1598888..bf59d1d 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/Version.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/Version.html
@@ -18,9 +18,9 @@
 <span class="sourceLineNo">010</span>  justification="Intentional; to be modified in test")<a name="line.10"></a>
 <span class="sourceLineNo">011</span>public class Version {<a name="line.11"></a>
 <span class="sourceLineNo">012</span>  public static final String version = new String("3.0.0-SNAPSHOT");<a name="line.12"></a>
-<span class="sourceLineNo">013</span>  public static final String revision = "0cd70ed89cbf7a77f7e53f09627ef7889eaca4ab";<a name="line.13"></a>
+<span class="sourceLineNo">013</span>  public static final String revision = "2774510e2bd70968a76a9f77df51ce987453aeba";<a name="line.13"></a>
 <span class="sourceLineNo">014</span>  public static final String user = "jenkins";<a name="line.14"></a>
-<span class="sourceLineNo">015</span>  public static final String date = "Fri May  8 14:39:16 UTC 2020";<a name="line.15"></a>
+<span class="sourceLineNo">015</span>  public static final String date = "Sat May  9 14:39:54 UTC 2020";<a name="line.15"></a>
 <span class="sourceLineNo">016</span>  public static final String url = "git://jenkins-websites-he-de.apache.org/home/jenkins/jenkins-slave/workspace/hbase_generate_website/hbase";<a name="line.16"></a>
 <span class="sourceLineNo">017</span>  public static final String srcChecksum = "(stdin)=";<a name="line.17"></a>
 <span class="sourceLineNo">018</span>}<a name="line.18"></a>
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html
index b671ca9..594c720 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/MetaFixer.Either.html
@@ -28,335 +28,358 @@
 <span class="sourceLineNo">020</span>import java.io.IOException;<a name="line.20"></a>
 <span class="sourceLineNo">021</span>import java.util.ArrayList;<a name="line.21"></a>
 <span class="sourceLineNo">022</span>import java.util.Collections;<a name="line.22"></a>
-<span class="sourceLineNo">023</span>import java.util.List;<a name="line.23"></a>
-<span class="sourceLineNo">024</span>import java.util.Optional;<a name="line.24"></a>
-<span class="sourceLineNo">025</span>import java.util.Set;<a name="line.25"></a>
-<span class="sourceLineNo">026</span>import java.util.SortedSet;<a name="line.26"></a>
-<span class="sourceLineNo">027</span>import java.util.TreeSet;<a name="line.27"></a>
-<span class="sourceLineNo">028</span>import java.util.stream.Collectors;<a name="line.28"></a>
-<span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.HConstants;<a name="line.29"></a>
-<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.MetaTableAccessor;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.TableName;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.client.RegionInfoBuilder;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.exceptions.MergeRegionException;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.master.assignment.TransitRegionStateProcedure;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import org.apache.hadoop.hbase.util.Pair;<a name="line.37"></a>
-<span class="sourceLineNo">038</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.38"></a>
-<span class="sourceLineNo">039</span>import org.slf4j.Logger;<a name="line.39"></a>
-<span class="sourceLineNo">040</span>import org.slf4j.LoggerFactory;<a name="line.40"></a>
-<span class="sourceLineNo">041</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.41"></a>
-<span class="sourceLineNo">042</span><a name="line.42"></a>
+<span class="sourceLineNo">023</span>import java.util.HashSet;<a name="line.23"></a>
+<span class="sourceLineNo">024</span>import java.util.List;<a name="line.24"></a>
+<span class="sourceLineNo">025</span>import java.util.Optional;<a name="line.25"></a>
+<span class="sourceLineNo">026</span>import java.util.Set;<a name="line.26"></a>
+<span class="sourceLineNo">027</span>import java.util.SortedSet;<a name="line.27"></a>
+<span class="sourceLineNo">028</span>import java.util.TreeSet;<a name="line.28"></a>
+<span class="sourceLineNo">029</span>import java.util.stream.Collectors;<a name="line.29"></a>
+<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.HConstants;<a name="line.30"></a>
+<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.MetaTableAccessor;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.TableName;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.client.RegionInfoBuilder;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.exceptions.MergeRegionException;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.master.assignment.TransitRegionStateProcedure;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import org.apache.hadoop.hbase.util.Pair;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.39"></a>
+<span class="sourceLineNo">040</span>import org.slf4j.Logger;<a name="line.40"></a>
+<span class="sourceLineNo">041</span>import org.slf4j.LoggerFactory;<a name="line.41"></a>
+<span class="sourceLineNo">042</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.42"></a>
 <span class="sourceLineNo">043</span><a name="line.43"></a>
-<span class="sourceLineNo">044</span>/**<a name="line.44"></a>
-<span class="sourceLineNo">045</span> * Server-side fixing of bad or inconsistent state in hbase:meta.<a name="line.45"></a>
-<span class="sourceLineNo">046</span> * Distinct from MetaTableAccessor because {@link MetaTableAccessor} is about low-level<a name="line.46"></a>
-<span class="sourceLineNo">047</span> * manipulations driven by the Master. This class MetaFixer is<a name="line.47"></a>
-<span class="sourceLineNo">048</span> * employed by the Master and it 'knows' about holes and orphans<a name="line.48"></a>
-<span class="sourceLineNo">049</span> * and encapsulates their fixing on behalf of the Master.<a name="line.49"></a>
-<span class="sourceLineNo">050</span> */<a name="line.50"></a>
-<span class="sourceLineNo">051</span>@InterfaceAudience.Private<a name="line.51"></a>
-<span class="sourceLineNo">052</span>class MetaFixer {<a name="line.52"></a>
-<span class="sourceLineNo">053</span>  private static final Logger LOG = LoggerFactory.getLogger(MetaFixer.class);<a name="line.53"></a>
-<span class="sourceLineNo">054</span>  private static final String MAX_MERGE_COUNT_KEY = "hbase.master.metafixer.max.merge.count";<a name="line.54"></a>
-<span class="sourceLineNo">055</span>  private static final int MAX_MERGE_COUNT_DEFAULT = 64;<a name="line.55"></a>
-<span class="sourceLineNo">056</span><a name="line.56"></a>
-<span class="sourceLineNo">057</span>  private final MasterServices masterServices;<a name="line.57"></a>
-<span class="sourceLineNo">058</span>  /**<a name="line.58"></a>
-<span class="sourceLineNo">059</span>   * Maximum for many regions to merge at a time.<a name="line.59"></a>
-<span class="sourceLineNo">060</span>   */<a name="line.60"></a>
-<span class="sourceLineNo">061</span>  private final int maxMergeCount;<a name="line.61"></a>
-<span class="sourceLineNo">062</span><a name="line.62"></a>
-<span class="sourceLineNo">063</span>  MetaFixer(MasterServices masterServices) {<a name="line.63"></a>
-<span class="sourceLineNo">064</span>    this.masterServices = masterServices;<a name="line.64"></a>
-<span class="sourceLineNo">065</span>    this.maxMergeCount = this.masterServices.getConfiguration().<a name="line.65"></a>
-<span class="sourceLineNo">066</span>      getInt(MAX_MERGE_COUNT_KEY, MAX_MERGE_COUNT_DEFAULT);<a name="line.66"></a>
-<span class="sourceLineNo">067</span>  }<a name="line.67"></a>
-<span class="sourceLineNo">068</span><a name="line.68"></a>
-<span class="sourceLineNo">069</span>  void fix() throws IOException {<a name="line.69"></a>
-<span class="sourceLineNo">070</span>    CatalogJanitor.Report report = this.masterServices.getCatalogJanitor().getLastReport();<a name="line.70"></a>
-<span class="sourceLineNo">071</span>    if (report == null) {<a name="line.71"></a>
-<span class="sourceLineNo">072</span>      LOG.info("CatalogJanitor has not generated a report yet; run 'catalogjanitor_run' in " +<a name="line.72"></a>
-<span class="sourceLineNo">073</span>          "shell or wait until CatalogJanitor chore runs.");<a name="line.73"></a>
-<span class="sourceLineNo">074</span>      return;<a name="line.74"></a>
-<span class="sourceLineNo">075</span>    }<a name="line.75"></a>
-<span class="sourceLineNo">076</span>    fixHoles(report);<a name="line.76"></a>
-<span class="sourceLineNo">077</span>    fixOverlaps(report);<a name="line.77"></a>
-<span class="sourceLineNo">078</span>    // Run the ReplicationBarrierCleaner here; it may clear out rep_barrier rows which<a name="line.78"></a>
-<span class="sourceLineNo">079</span>    // can help cleaning up damaged hbase:meta.<a name="line.79"></a>
-<span class="sourceLineNo">080</span>    this.masterServices.runReplicationBarrierCleaner();<a name="line.80"></a>
-<span class="sourceLineNo">081</span>  }<a name="line.81"></a>
-<span class="sourceLineNo">082</span><a name="line.82"></a>
-<span class="sourceLineNo">083</span>  /**<a name="line.83"></a>
-<span class="sourceLineNo">084</span>   * If hole, it papers it over by adding a region in the filesystem and to hbase:meta.<a name="line.84"></a>
-<span class="sourceLineNo">085</span>   * Does not assign.<a name="line.85"></a>
-<span class="sourceLineNo">086</span>   */<a name="line.86"></a>
-<span class="sourceLineNo">087</span>  void fixHoles(CatalogJanitor.Report report) {<a name="line.87"></a>
-<span class="sourceLineNo">088</span>    final List&lt;Pair&lt;RegionInfo, RegionInfo&gt;&gt; holes = report.getHoles();<a name="line.88"></a>
-<span class="sourceLineNo">089</span>    if (holes.isEmpty()) {<a name="line.89"></a>
-<span class="sourceLineNo">090</span>      LOG.info("CatalogJanitor Report contains no holes to fix. Skipping.");<a name="line.90"></a>
-<span class="sourceLineNo">091</span>      return;<a name="line.91"></a>
-<span class="sourceLineNo">092</span>    }<a name="line.92"></a>
-<span class="sourceLineNo">093</span><a name="line.93"></a>
-<span class="sourceLineNo">094</span>    LOG.info("Identified {} region holes to fix. Detailed fixup progress logged at DEBUG.",<a name="line.94"></a>
-<span class="sourceLineNo">095</span>      holes.size());<a name="line.95"></a>
-<span class="sourceLineNo">096</span><a name="line.96"></a>
-<span class="sourceLineNo">097</span>    final List&lt;RegionInfo&gt; newRegionInfos = createRegionInfosForHoles(holes);<a name="line.97"></a>
-<span class="sourceLineNo">098</span>    final List&lt;RegionInfo&gt; newMetaEntries = createMetaEntries(masterServices, newRegionInfos);<a name="line.98"></a>
-<span class="sourceLineNo">099</span>    final TransitRegionStateProcedure[] assignProcedures = masterServices<a name="line.99"></a>
-<span class="sourceLineNo">100</span>      .getAssignmentManager()<a name="line.100"></a>
-<span class="sourceLineNo">101</span>      .createRoundRobinAssignProcedures(newMetaEntries);<a name="line.101"></a>
-<span class="sourceLineNo">102</span><a name="line.102"></a>
-<span class="sourceLineNo">103</span>    masterServices.getMasterProcedureExecutor().submitProcedures(assignProcedures);<a name="line.103"></a>
-<span class="sourceLineNo">104</span>    LOG.info(<a name="line.104"></a>
-<span class="sourceLineNo">105</span>      "Scheduled {}/{} new regions for assignment.", assignProcedures.length, holes.size());<a name="line.105"></a>
-<span class="sourceLineNo">106</span>  }<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>   * Create a new {@link RegionInfo} corresponding to each provided "hole" pair.<a name="line.109"></a>
-<span class="sourceLineNo">110</span>   */<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  private static List&lt;RegionInfo&gt; createRegionInfosForHoles(<a name="line.111"></a>
-<span class="sourceLineNo">112</span>    final List&lt;Pair&lt;RegionInfo, RegionInfo&gt;&gt; holes) {<a name="line.112"></a>
-<span class="sourceLineNo">113</span>    final List&lt;RegionInfo&gt; newRegionInfos = holes.stream()<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      .map(MetaFixer::getHoleCover)<a name="line.114"></a>
-<span class="sourceLineNo">115</span>      .filter(Optional::isPresent)<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      .map(Optional::get)<a name="line.116"></a>
-<span class="sourceLineNo">117</span>      .collect(Collectors.toList());<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    LOG.debug("Constructed {}/{} RegionInfo descriptors corresponding to identified holes.",<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      newRegionInfos.size(), holes.size());<a name="line.119"></a>
-<span class="sourceLineNo">120</span>    return newRegionInfos;<a name="line.120"></a>
-<span class="sourceLineNo">121</span>  }<a name="line.121"></a>
-<span class="sourceLineNo">122</span><a name="line.122"></a>
-<span class="sourceLineNo">123</span>  /**<a name="line.123"></a>
-<span class="sourceLineNo">124</span>   * @return Attempts to calculate a new {@link RegionInfo} that covers the region range described<a name="line.124"></a>
-<span class="sourceLineNo">125</span>   *   in {@code hole}.<a name="line.125"></a>
-<span class="sourceLineNo">126</span>   */<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private static Optional&lt;RegionInfo&gt; getHoleCover(Pair&lt;RegionInfo, RegionInfo&gt; hole) {<a name="line.127"></a>
-<span class="sourceLineNo">128</span>    final RegionInfo left = hole.getFirst();<a name="line.128"></a>
-<span class="sourceLineNo">129</span>    final RegionInfo right = hole.getSecond();<a name="line.129"></a>
-<span class="sourceLineNo">130</span><a name="line.130"></a>
-<span class="sourceLineNo">131</span>    if (left.getTable().equals(right.getTable())) {<a name="line.131"></a>
-<span class="sourceLineNo">132</span>      // Simple case.<a name="line.132"></a>
-<span class="sourceLineNo">133</span>      if (Bytes.compareTo(left.getEndKey(), right.getStartKey()) &gt;= 0) {<a name="line.133"></a>
-<span class="sourceLineNo">134</span>        LOG.warn("Skipping hole fix; left-side endKey is not less than right-side startKey;"<a name="line.134"></a>
-<span class="sourceLineNo">135</span>          + " left=&lt;{}&gt;, right=&lt;{}&gt;", left, right);<a name="line.135"></a>
-<span class="sourceLineNo">136</span>        return Optional.empty();<a name="line.136"></a>
-<span class="sourceLineNo">137</span>      }<a name="line.137"></a>
-<span class="sourceLineNo">138</span>      return Optional.of(buildRegionInfo(left.getTable(), left.getEndKey(), right.getStartKey()));<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>    final boolean leftUndefined = left.equals(RegionInfo.UNDEFINED);<a name="line.141"></a>
-<span class="sourceLineNo">142</span>    final boolean rightUndefined = right.equals(RegionInfo.UNDEFINED);<a name="line.142"></a>
-<span class="sourceLineNo">143</span>    final boolean last = left.isLast();<a name="line.143"></a>
-<span class="sourceLineNo">144</span>    final boolean first = right.isFirst();<a name="line.144"></a>
-<span class="sourceLineNo">145</span>    if (leftUndefined &amp;&amp; rightUndefined) {<a name="line.145"></a>
-<span class="sourceLineNo">146</span>      LOG.warn("Skipping hole fix; both the hole left-side and right-side RegionInfos are " +<a name="line.146"></a>
-<span class="sourceLineNo">147</span>        "UNDEFINED; left=&lt;{}&gt;, right=&lt;{}&gt;", left, right);<a name="line.147"></a>
-<span class="sourceLineNo">148</span>      return Optional.empty();<a name="line.148"></a>
-<span class="sourceLineNo">149</span>    }<a name="line.149"></a>
-<span class="sourceLineNo">150</span>    if (leftUndefined || last) {<a name="line.150"></a>
-<span class="sourceLineNo">151</span>      return Optional.of(<a name="line.151"></a>
-<span class="sourceLineNo">152</span>        buildRegionInfo(right.getTable(), HConstants.EMPTY_START_ROW, right.getStartKey()));<a name="line.152"></a>
-<span class="sourceLineNo">153</span>    }<a name="line.153"></a>
-<span class="sourceLineNo">154</span>    if (rightUndefined || first) {<a name="line.154"></a>
-<span class="sourceLineNo">155</span>      return Optional.of(<a name="line.155"></a>
-<span class="sourceLineNo">156</span>        buildRegionInfo(left.getTable(), left.getEndKey(), HConstants.EMPTY_END_ROW));<a name="line.156"></a>
-<span class="sourceLineNo">157</span>    }<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    LOG.warn("Skipping hole fix; don't know what to do with left=&lt;{}&gt;, right=&lt;{}&gt;", left, right);<a name="line.158"></a>
-<span class="sourceLineNo">159</span>    return Optional.empty();<a name="line.159"></a>
-<span class="sourceLineNo">160</span>  }<a name="line.160"></a>
-<span class="sourceLineNo">161</span><a name="line.161"></a>
-<span class="sourceLineNo">162</span>  private static RegionInfo buildRegionInfo(TableName tn, byte [] start, byte [] end) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    return RegionInfoBuilder.newBuilder(tn).setStartKey(start).setEndKey(end).build();<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  /**<a name="line.166"></a>
-<span class="sourceLineNo">167</span>   * Create entries in the {@code hbase:meta} for each provided {@link RegionInfo}. Best effort.<a name="line.167"></a>
-<span class="sourceLineNo">168</span>   * @param masterServices used to connect to {@code hbase:meta}<a name="line.168"></a>
-<span class="sourceLineNo">169</span>   * @param newRegionInfos the new {@link RegionInfo} entries to add to the filesystem<a name="line.169"></a>
-<span class="sourceLineNo">170</span>   * @return a list of {@link RegionInfo} entries for which {@code hbase:meta} entries were<a name="line.170"></a>
-<span class="sourceLineNo">171</span>   *   successfully created<a name="line.171"></a>
-<span class="sourceLineNo">172</span>   */<a name="line.172"></a>
-<span class="sourceLineNo">173</span>  private static List&lt;RegionInfo&gt; createMetaEntries(final MasterServices masterServices,<a name="line.173"></a>
-<span class="sourceLineNo">174</span>    final List&lt;RegionInfo&gt; newRegionInfos) {<a name="line.174"></a>
-<span class="sourceLineNo">175</span><a name="line.175"></a>
-<span class="sourceLineNo">176</span>    final List&lt;Either&lt;RegionInfo, IOException&gt;&gt; addMetaEntriesResults = newRegionInfos.stream()<a name="line.176"></a>
-<span class="sourceLineNo">177</span>      .map(regionInfo -&gt; {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>        try {<a name="line.178"></a>
-<span class="sourceLineNo">179</span>          MetaTableAccessor.addRegionToMeta(masterServices.getConnection(), regionInfo);<a name="line.179"></a>
-<span class="sourceLineNo">180</span>          masterServices.getAssignmentManager()<a name="line.180"></a>
-<span class="sourceLineNo">181</span>            .getRegionStates()<a name="line.181"></a>
-<span class="sourceLineNo">182</span>            .updateRegionState(regionInfo, RegionState.State.CLOSED);<a name="line.182"></a>
-<span class="sourceLineNo">183</span>          return Either.&lt;RegionInfo, IOException&gt;ofLeft(regionInfo);<a name="line.183"></a>
-<span class="sourceLineNo">184</span>        } catch (IOException e) {<a name="line.184"></a>
-<span class="sourceLineNo">185</span>          return Either.&lt;RegionInfo, IOException&gt;ofRight(e);<a name="line.185"></a>
-<span class="sourceLineNo">186</span>        }<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      })<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      .collect(Collectors.toList());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    final List&lt;RegionInfo&gt; createMetaEntriesSuccesses = addMetaEntriesResults.stream()<a name="line.189"></a>
-<span class="sourceLineNo">190</span>      .filter(Either::hasLeft)<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      .map(Either::getLeft)<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      .collect(Collectors.toList());<a name="line.192"></a>
-<span class="sourceLineNo">193</span>    final List&lt;IOException&gt; createMetaEntriesFailures = addMetaEntriesResults.stream()<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      .filter(Either::hasRight)<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      .map(Either::getRight)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>      .collect(Collectors.toList());<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    LOG.debug("Added {}/{} entries to hbase:meta",<a name="line.197"></a>
-<span class="sourceLineNo">198</span>      createMetaEntriesSuccesses.size(), newRegionInfos.size());<a name="line.198"></a>
-<span class="sourceLineNo">199</span><a name="line.199"></a>
-<span class="sourceLineNo">200</span>    if (!createMetaEntriesFailures.isEmpty()) {<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      LOG.warn("Failed to create entries in hbase:meta for {}/{} RegionInfo descriptors. First"<a name="line.201"></a>
-<span class="sourceLineNo">202</span>          + " failure message included; full list of failures with accompanying stack traces is"<a name="line.202"></a>
-<span class="sourceLineNo">203</span>          + " available at log level DEBUG. message={}", createMetaEntriesFailures.size(),<a name="line.203"></a>
-<span class="sourceLineNo">204</span>        addMetaEntriesResults.size(), createMetaEntriesFailures.get(0).getMessage());<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      if (LOG.isDebugEnabled()) {<a name="line.205"></a>
-<span class="sourceLineNo">206</span>        createMetaEntriesFailures.forEach(<a name="line.206"></a>
-<span class="sourceLineNo">207</span>          ioe -&gt; LOG.debug("Attempt to fix region hole in hbase:meta failed.", ioe));<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      }<a name="line.208"></a>
-<span class="sourceLineNo">209</span>    }<a name="line.209"></a>
-<span class="sourceLineNo">210</span><a name="line.210"></a>
-<span class="sourceLineNo">211</span>    return createMetaEntriesSuccesses;<a name="line.211"></a>
-<span class="sourceLineNo">212</span>  }<a name="line.212"></a>
-<span class="sourceLineNo">213</span><a name="line.213"></a>
-<span class="sourceLineNo">214</span>  /**<a name="line.214"></a>
-<span class="sourceLineNo">215</span>   * Fix overlaps noted in CJ consistency report.<a name="line.215"></a>
-<span class="sourceLineNo">216</span>   */<a name="line.216"></a>
-<span class="sourceLineNo">217</span>  void fixOverlaps(CatalogJanitor.Report report) throws IOException {<a name="line.217"></a>
-<span class="sourceLineNo">218</span>    for (Set&lt;RegionInfo&gt; regions: calculateMerges(maxMergeCount, report.getOverlaps())) {<a name="line.218"></a>
-<span class="sourceLineNo">219</span>      RegionInfo [] regionsArray = regions.toArray(new RegionInfo [] {});<a name="line.219"></a>
-<span class="sourceLineNo">220</span>      try {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>        this.masterServices.mergeRegions(regionsArray,<a name="line.221"></a>
-<span class="sourceLineNo">222</span>            true, HConstants.NO_NONCE, HConstants.NO_NONCE);<a name="line.222"></a>
-<span class="sourceLineNo">223</span>      } catch (MergeRegionException mre) {<a name="line.223"></a>
-<span class="sourceLineNo">224</span>        LOG.warn("Failed overlap fix of {}", regionsArray, mre);<a name="line.224"></a>
-<span class="sourceLineNo">225</span>      }<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    }<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  /**<a name="line.229"></a>
-<span class="sourceLineNo">230</span>   * Run through &lt;code&gt;overlaps&lt;/code&gt; and return a list of merges to run.<a name="line.230"></a>
-<span class="sourceLineNo">231</span>   * Presumes overlaps are ordered (which they are coming out of the CatalogJanitor<a name="line.231"></a>
-<span class="sourceLineNo">232</span>   * consistency report).<a name="line.232"></a>
-<span class="sourceLineNo">233</span>   * @param maxMergeCount Maximum regions to merge at a time (avoid merging<a name="line.233"></a>
-<span class="sourceLineNo">234</span>   *   100k regions in one go!)<a name="line.234"></a>
-<span class="sourceLineNo">235</span>   */<a name="line.235"></a>
-<span class="sourceLineNo">236</span>  @VisibleForTesting<a name="line.236"></a>
-<span class="sourceLineNo">237</span>  static List&lt;SortedSet&lt;RegionInfo&gt;&gt; calculateMerges(int maxMergeCount,<a name="line.237"></a>
-<span class="sourceLineNo">238</span>      List&lt;Pair&lt;RegionInfo, RegionInfo&gt;&gt; overlaps) {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>    if (overlaps.isEmpty()) {<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      LOG.debug("No overlaps.");<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      return Collections.emptyList();<a name="line.241"></a>
-<span class="sourceLineNo">242</span>    }<a name="line.242"></a>
-<span class="sourceLineNo">243</span>    List&lt;SortedSet&lt;RegionInfo&gt;&gt; merges = new ArrayList&lt;&gt;();<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    SortedSet&lt;RegionInfo&gt; currentMergeSet = new TreeSet&lt;&gt;();<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    RegionInfo regionInfoWithlargestEndKey =  null;<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    for (Pair&lt;RegionInfo, RegionInfo&gt; pair: overlaps) {<a name="line.246"></a>
-<span class="sourceLineNo">247</span>      if (regionInfoWithlargestEndKey != null) {<a name="line.247"></a>
-<span class="sourceLineNo">248</span>        if (!isOverlap(regionInfoWithlargestEndKey, pair) ||<a name="line.248"></a>
-<span class="sourceLineNo">249</span>            currentMergeSet.size() &gt;= maxMergeCount) {<a name="line.249"></a>
-<span class="sourceLineNo">250</span>          // Log when we cut-off-merge because we hit the configured maximum merge limit.<a name="line.250"></a>
-<span class="sourceLineNo">251</span>          if (currentMergeSet.size() &gt;= maxMergeCount) {<a name="line.251"></a>
-<span class="sourceLineNo">252</span>            LOG.warn("Ran into maximum-at-a-time merges limit={}", maxMergeCount);<a name="line.252"></a>
-<span class="sourceLineNo">253</span>          }<a name="line.253"></a>
-<span class="sourceLineNo">254</span>          merges.add(currentMergeSet);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>          currentMergeSet = new TreeSet&lt;&gt;();<a name="line.255"></a>
-<span class="sourceLineNo">256</span>        }<a name="line.256"></a>
-<span class="sourceLineNo">257</span>      }<a name="line.257"></a>
-<span class="sourceLineNo">258</span>      currentMergeSet.add(pair.getFirst());<a name="line.258"></a>
-<span class="sourceLineNo">259</span>      currentMergeSet.add(pair.getSecond());<a name="line.259"></a>
-<span class="sourceLineNo">260</span>      regionInfoWithlargestEndKey = getRegionInfoWithLargestEndKey(<a name="line.260"></a>
-<span class="sourceLineNo">261</span>        getRegionInfoWithLargestEndKey(pair.getFirst(), pair.getSecond()),<a name="line.261"></a>
-<span class="sourceLineNo">262</span>          regionInfoWithlargestEndKey);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    }<a name="line.263"></a>
-<span class="sourceLineNo">264</span>    merges.add(currentMergeSet);<a name="line.264"></a>
-<span class="sourceLineNo">265</span>    return merges;<a name="line.265"></a>
-<span class="sourceLineNo">266</span>  }<a name="line.266"></a>
-<span class="sourceLineNo">267</span><a name="line.267"></a>
-<span class="sourceLineNo">268</span>  /**<a name="line.268"></a>
-<span class="sourceLineNo">269</span>   * @return Either &lt;code&gt;a&lt;/code&gt; or &lt;code&gt;b&lt;/code&gt;, whichever has the<a name="line.269"></a>
-<span class="sourceLineNo">270</span>   *   endkey that is furthest along in the Table.<a name="line.270"></a>
-<span class="sourceLineNo">271</span>   */<a name="line.271"></a>
-<span class="sourceLineNo">272</span>  @VisibleForTesting<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  static RegionInfo getRegionInfoWithLargestEndKey(RegionInfo a, RegionInfo b) {<a name="line.273"></a>
-<span class="sourceLineNo">274</span>    if (a == null) {<a name="line.274"></a>
-<span class="sourceLineNo">275</span>      // b may be null.<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      return b;<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    }<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (b == null) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      // Both are null. The return is not-defined.<a name="line.279"></a>
-<span class="sourceLineNo">280</span>      return a;<a name="line.280"></a>
-<span class="sourceLineNo">281</span>    }<a name="line.281"></a>
-<span class="sourceLineNo">282</span>    if (!a.getTable().equals(b.getTable())) {<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      // This is an odd one. This should be the right answer.<a name="line.283"></a>
-<span class="sourceLineNo">284</span>      return b;<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    }<a name="line.285"></a>
-<span class="sourceLineNo">286</span>    if (a.isLast()) {<a name="line.286"></a>
-<span class="sourceLineNo">287</span>      return a;<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    }<a name="line.288"></a>
-<span class="sourceLineNo">289</span>    if (b.isLast()) {<a name="line.289"></a>
-<span class="sourceLineNo">290</span>      return b;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    }<a name="line.291"></a>
-<span class="sourceLineNo">292</span>    int compare = Bytes.compareTo(a.getEndKey(), b.getEndKey());<a name="line.292"></a>
-<span class="sourceLineNo">293</span>    return compare == 0 || compare &gt; 0? a: b;<a name="line.293"></a>
-<span class="sourceLineNo">294</span>  }<a name="line.294"></a>
-<span class="sourceLineNo">295</span><a name="line.295"></a>
-<span class="sourceLineNo">296</span>  /**<a name="line.296"></a>
-<span class="sourceLineNo">297</span>   * @return True if an overlap found between passed in &lt;code&gt;ri&lt;/code&gt; and<a name="line.297"></a>
-<span class="sourceLineNo">298</span>   *   the &lt;code&gt;pair&lt;/code&gt;. Does NOT check the pairs themselves overlap.<a name="line.298"></a>
-<span class="sourceLineNo">299</span>   */<a name="line.299"></a>
-<span class="sourceLineNo">300</span>  @VisibleForTesting<a name="line.300"></a>
-<span class="sourceLineNo">301</span>  static boolean isOverlap(RegionInfo ri, Pair&lt;RegionInfo, RegionInfo&gt; pair) {<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    if (ri == null || pair == null) {<a name="line.302"></a>
-<span class="sourceLineNo">303</span>      // Can't be an overlap in either of these cases.<a name="line.303"></a>
-<span class="sourceLineNo">304</span>      return false;<a name="line.304"></a>
-<span class="sourceLineNo">305</span>    }<a name="line.305"></a>
-<span class="sourceLineNo">306</span>    return ri.isOverlap(pair.getFirst()) || ri.isOverlap(pair.getSecond());<a name="line.306"></a>
-<span class="sourceLineNo">307</span>  }<a name="line.307"></a>
-<span class="sourceLineNo">308</span><a name="line.308"></a>
-<span class="sourceLineNo">309</span>  /**<a name="line.309"></a>
-<span class="sourceLineNo">310</span>   * A union over {@link L} and {@link R}.<a name="line.310"></a>
-<span class="sourceLineNo">311</span>   */<a name="line.311"></a>
-<span class="sourceLineNo">312</span>  private static class Either&lt;L, R&gt; {<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    private final L left;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>    private final R right;<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>    public static &lt;L, R&gt; Either&lt;L, R&gt; ofLeft(L left) {<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      return new Either&lt;&gt;(left, null);<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    }<a name="line.318"></a>
-<span class="sourceLineNo">319</span><a name="line.319"></a>
-<span class="sourceLineNo">320</span>    public static &lt;L, R&gt; Either&lt;L, R&gt; ofRight(R right) {<a name="line.320"></a>
-<span class="sourceLineNo">321</span>      return new Either&lt;&gt;(null, right);<a name="line.321"></a>
-<span class="sourceLineNo">322</span>    }<a name="line.322"></a>
-<span class="sourceLineNo">323</span><a name="line.323"></a>
-<span class="sourceLineNo">324</span>    Either(L left, R right) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>      this.left = left;<a name="line.325"></a>
-<span class="sourceLineNo">326</span>      this.right = right;<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>    public boolean hasLeft() {<a name="line.329"></a>
-<span class="sourceLineNo">330</span>      return left != null;<a name="line.330"></a>
-<span class="sourceLineNo">331</span>    }<a name="line.331"></a>
-<span class="sourceLineNo">332</span><a name="line.332"></a>
-<span class="sourceLineNo">333</span>    public L getLeft() {<a name="line.333"></a>
-<span class="sourceLineNo">334</span>      if (!hasLeft()) {<a name="line.334"></a>
-<span class="sourceLineNo">335</span>        throw new IllegalStateException("Either contains no left.");<a name="line.335"></a>
-<span class="sourceLineNo">336</span>      }<a name="line.336"></a>
-<span class="sourceLineNo">337</span>      return left;<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>    public boolean hasRight() {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>      return right != null;<a name="line.341"></a>
-<span class="sourceLineNo">342</span>    }<a name="line.342"></a>
-<span class="sourceLineNo">343</span><a name="line.343"></a>
-<span class="sourceLineNo">344</span>    public R getRight() {<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      if (!hasRight()) {<a name="line.345"></a>
-<span class="sourceLineNo">346</span>        throw new IllegalStateException("Either contains no right.");<a name="line.346"></a>
-<span class="sourceLineNo">347</span>      }<a name="line.347"></a>
-<span class="sourceLineNo">348</span>      return right;<a name="line.348"></a>
-<span class="sourceLineNo">349</span>    }<a name="line.349"></a>
-<span class="sourceLineNo">350</span>  }<a name="line.350"></a>
-<span class="sourceLineNo">351</span>}<a name="line.351"></a>
+<span class="sourceLineNo">044</span><a name="line.44"></a>
+<span class="sourceLineNo">045</span>/**<a name="line.45"></a>
+<span class="sourceLineNo">046</span> * Server-side fixing of bad or inconsistent state in hbase:meta.<a name="line.46"></a>
+<span class="sourceLineNo">047</span> * Distinct from MetaTableAccessor because {@link MetaTableAccessor} is about low-level<a name="line.47"></a>
+<span class="sourceLineNo">048</span> * manipulations driven by the Master. This class MetaFixer is<a name="line.48"></a>
+<span class="sourceLineNo">049</span> * employed by the Master and it 'knows' about holes and orphans<a name="line.49"></a>
+<span class="sourceLineNo">050</span> * and encapsulates their fixing on behalf of the Master.<a name="line.50"></a>
+<span class="sourceLineNo">051</span> */<a name="line.51"></a>
+<span class="sourceLineNo">052</span>@InterfaceAudience.Private<a name="line.52"></a>
+<span class="sourceLineNo">053</span>class MetaFixer {<a name="line.53"></a>
+<span class="sourceLineNo">054</span>  private static final Logger LOG = LoggerFactory.getLogger(MetaFixer.class);<a name="line.54"></a>
+<span class="sourceLineNo">055</span>  private static final String MAX_MERGE_COUNT_KEY = "hbase.master.metafixer.max.merge.count";<a name="line.55"></a>
+<span class="sourceLineNo">056</span>  private static final int MAX_MERGE_COUNT_DEFAULT = 64;<a name="line.56"></a>
+<span class="sourceLineNo">057</span><a name="line.57"></a>
+<span class="sourceLineNo">058</span>  private final MasterServices masterServices;<a name="line.58"></a>
+<span class="sourceLineNo">059</span>  /**<a name="line.59"></a>
+<span class="sourceLineNo">060</span>   * Maximum for many regions to merge at a time.<a name="line.60"></a>
+<span class="sourceLineNo">061</span>   */<a name="line.61"></a>
+<span class="sourceLineNo">062</span>  private final int maxMergeCount;<a name="line.62"></a>
+<span class="sourceLineNo">063</span><a name="line.63"></a>
+<span class="sourceLineNo">064</span>  MetaFixer(MasterServices masterServices) {<a name="line.64"></a>
+<span class="sourceLineNo">065</span>    this.masterServices = masterServices;<a name="line.65"></a>
+<span class="sourceLineNo">066</span>    this.maxMergeCount = this.masterServices.getConfiguration().<a name="line.66"></a>
+<span class="sourceLineNo">067</span>      getInt(MAX_MERGE_COUNT_KEY, MAX_MERGE_COUNT_DEFAULT);<a name="line.67"></a>
+<span class="sourceLineNo">068</span>  }<a name="line.68"></a>
+<span class="sourceLineNo">069</span><a name="line.69"></a>
+<span class="sourceLineNo">070</span>  void fix() throws IOException {<a name="line.70"></a>
+<span class="sourceLineNo">071</span>    CatalogJanitor.Report report = this.masterServices.getCatalogJanitor().getLastReport();<a name="line.71"></a>
+<span class="sourceLineNo">072</span>    if (report == null) {<a name="line.72"></a>
+<span class="sourceLineNo">073</span>      LOG.info("CatalogJanitor has not generated a report yet; run 'catalogjanitor_run' in " +<a name="line.73"></a>
+<span class="sourceLineNo">074</span>          "shell or wait until CatalogJanitor chore runs.");<a name="line.74"></a>
+<span class="sourceLineNo">075</span>      return;<a name="line.75"></a>
+<span class="sourceLineNo">076</span>    }<a name="line.76"></a>
+<span class="sourceLineNo">077</span>    fixHoles(report);<a name="line.77"></a>
+<span class="sourceLineNo">078</span>    fixOverlaps(report);<a name="line.78"></a>
+<span class="sourceLineNo">079</span>    // Run the ReplicationBarrierCleaner here; it may clear out rep_barrier rows which<a name="line.79"></a>
+<span class="sourceLineNo">080</span>    // can help cleaning up damaged hbase:meta.<a name="line.80"></a>
+<span class="sourceLineNo">081</span>    this.masterServices.runReplicationBarrierCleaner();<a name="line.81"></a>
+<span class="sourceLineNo">082</span>  }<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>   * If hole, it papers it over by adding a region in the filesystem and to hbase:meta.<a name="line.85"></a>
+<span class="sourceLineNo">086</span>   * Does not assign.<a name="line.86"></a>
+<span class="sourceLineNo">087</span>   */<a name="line.87"></a>
+<span class="sourceLineNo">088</span>  void fixHoles(CatalogJanitor.Report report) {<a name="line.88"></a>
+<span class="sourceLineNo">089</span>    final List&lt;Pair&lt;RegionInfo, RegionInfo&gt;&gt; holes = report.getHoles();<a name="line.89"></a>
+<span class="sourceLineNo">090</span>    if (holes.isEmpty()) {<a name="line.90"></a>
+<span class="sourceLineNo">091</span>      LOG.info("CatalogJanitor Report contains no holes to fix. Skipping.");<a name="line.91"></a>
+<span class="sourceLineNo">092</span>      return;<a name="line.92"></a>
+<span class="sourceLineNo">093</span>    }<a name="line.93"></a>
+<span class="sourceLineNo">094</span><a name="line.94"></a>
+<span class="sourceLineNo">095</span>    LOG.info("Identified {} region holes to fix. Detailed fixup progress logged at DEBUG.",<a name="line.95"></a>
+<span class="sourceLineNo">096</span>      holes.size());<a name="line.96"></a>
+<span class="sourceLineNo">097</span><a name="line.97"></a>
+<span class="sourceLineNo">098</span>    final List&lt;RegionInfo&gt; newRegionInfos = createRegionInfosForHoles(holes);<a name="line.98"></a>
+<span class="sourceLineNo">099</span>    final List&lt;RegionInfo&gt; newMetaEntries = createMetaEntries(masterServices, newRegionInfos);<a name="line.99"></a>
+<span class="sourceLineNo">100</span>    final TransitRegionStateProcedure[] assignProcedures = masterServices<a name="line.100"></a>
+<span class="sourceLineNo">101</span>      .getAssignmentManager()<a name="line.101"></a>
+<span class="sourceLineNo">102</span>      .createRoundRobinAssignProcedures(newMetaEntries);<a name="line.102"></a>
+<span class="sourceLineNo">103</span><a name="line.103"></a>
+<span class="sourceLineNo">104</span>    masterServices.getMasterProcedureExecutor().submitProcedures(assignProcedures);<a name="line.104"></a>
+<span class="sourceLineNo">105</span>    LOG.info(<a name="line.105"></a>
+<span class="sourceLineNo">106</span>      "Scheduled {}/{} new regions for assignment.", assignProcedures.length, holes.size());<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>
+<span class="sourceLineNo">110</span>   * Create a new {@link RegionInfo} corresponding to each provided "hole" pair.<a name="line.110"></a>
+<span class="sourceLineNo">111</span>   */<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  private static List&lt;RegionInfo&gt; createRegionInfosForHoles(<a name="line.112"></a>
+<span class="sourceLineNo">113</span>    final List&lt;Pair&lt;RegionInfo, RegionInfo&gt;&gt; holes) {<a name="line.113"></a>
+<span class="sourceLineNo">114</span>    final List&lt;RegionInfo&gt; newRegionInfos = holes.stream()<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      .map(MetaFixer::getHoleCover)<a name="line.115"></a>
+<span class="sourceLineNo">116</span>      .filter(Optional::isPresent)<a name="line.116"></a>
+<span class="sourceLineNo">117</span>      .map(Optional::get)<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      .collect(Collectors.toList());<a name="line.118"></a>
+<span class="sourceLineNo">119</span>    LOG.debug("Constructed {}/{} RegionInfo descriptors corresponding to identified holes.",<a name="line.119"></a>
+<span class="sourceLineNo">120</span>      newRegionInfos.size(), holes.size());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>    return newRegionInfos;<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>  /**<a name="line.124"></a>
+<span class="sourceLineNo">125</span>   * @return Attempts to calculate a new {@link RegionInfo} that covers the region range described<a name="line.125"></a>
+<span class="sourceLineNo">126</span>   *   in {@code hole}.<a name="line.126"></a>
+<span class="sourceLineNo">127</span>   */<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private static Optional&lt;RegionInfo&gt; getHoleCover(Pair&lt;RegionInfo, RegionInfo&gt; hole) {<a name="line.128"></a>
+<span class="sourceLineNo">129</span>    final RegionInfo left = hole.getFirst();<a name="line.129"></a>
+<span class="sourceLineNo">130</span>    final RegionInfo right = hole.getSecond();<a name="line.130"></a>
+<span class="sourceLineNo">131</span><a name="line.131"></a>
+<span class="sourceLineNo">132</span>    if (left.getTable().equals(right.getTable())) {<a name="line.132"></a>
+<span class="sourceLineNo">133</span>      // Simple case.<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      if (Bytes.compareTo(left.getEndKey(), right.getStartKey()) &gt;= 0) {<a name="line.134"></a>
+<span class="sourceLineNo">135</span>        LOG.warn("Skipping hole fix; left-side endKey is not less than right-side startKey;"<a name="line.135"></a>
+<span class="sourceLineNo">136</span>          + " left=&lt;{}&gt;, right=&lt;{}&gt;", left, right);<a name="line.136"></a>
+<span class="sourceLineNo">137</span>        return Optional.empty();<a name="line.137"></a>
+<span class="sourceLineNo">138</span>      }<a name="line.138"></a>
+<span class="sourceLineNo">139</span>      return Optional.of(buildRegionInfo(left.getTable(), left.getEndKey(), right.getStartKey()));<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>    final boolean leftUndefined = left.equals(RegionInfo.UNDEFINED);<a name="line.142"></a>
+<span class="sourceLineNo">143</span>    final boolean rightUndefined = right.equals(RegionInfo.UNDEFINED);<a name="line.143"></a>
+<span class="sourceLineNo">144</span>    final boolean last = left.isLast();<a name="line.144"></a>
+<span class="sourceLineNo">145</span>    final boolean first = right.isFirst();<a name="line.145"></a>
+<span class="sourceLineNo">146</span>    if (leftUndefined &amp;&amp; rightUndefined) {<a name="line.146"></a>
+<span class="sourceLineNo">147</span>      LOG.warn("Skipping hole fix; both the hole left-side and right-side RegionInfos are " +<a name="line.147"></a>
+<span class="sourceLineNo">148</span>        "UNDEFINED; left=&lt;{}&gt;, right=&lt;{}&gt;", left, right);<a name="line.148"></a>
+<span class="sourceLineNo">149</span>      return Optional.empty();<a name="line.149"></a>
+<span class="sourceLineNo">150</span>    }<a name="line.150"></a>
+<span class="sourceLineNo">151</span>    if (leftUndefined || last) {<a name="line.151"></a>
+<span class="sourceLineNo">152</span>      return Optional.of(<a name="line.152"></a>
+<span class="sourceLineNo">153</span>        buildRegionInfo(right.getTable(), HConstants.EMPTY_START_ROW, right.getStartKey()));<a name="line.153"></a>
+<span class="sourceLineNo">154</span>    }<a name="line.154"></a>
+<span class="sourceLineNo">155</span>    if (rightUndefined || first) {<a name="line.155"></a>
+<span class="sourceLineNo">156</span>      return Optional.of(<a name="line.156"></a>
+<span class="sourceLineNo">157</span>        buildRegionInfo(left.getTable(), left.getEndKey(), HConstants.EMPTY_END_ROW));<a name="line.157"></a>
+<span class="sourceLineNo">158</span>    }<a name="line.158"></a>
+<span class="sourceLineNo">159</span>    LOG.warn("Skipping hole fix; don't know what to do with left=&lt;{}&gt;, right=&lt;{}&gt;", left, right);<a name="line.159"></a>
+<span class="sourceLineNo">160</span>    return Optional.empty();<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  }<a name="line.161"></a>
+<span class="sourceLineNo">162</span><a name="line.162"></a>
+<span class="sourceLineNo">163</span>  private static RegionInfo buildRegionInfo(TableName tn, byte [] start, byte [] end) {<a name="line.163"></a>
+<span class="sourceLineNo">164</span>    return RegionInfoBuilder.newBuilder(tn).setStartKey(start).setEndKey(end).build();<a name="line.164"></a>
+<span class="sourceLineNo">165</span>  }<a name="line.165"></a>
+<span class="sourceLineNo">166</span><a name="line.166"></a>
+<span class="sourceLineNo">167</span>  /**<a name="line.167"></a>
+<span class="sourceLineNo">168</span>   * Create entries in the {@code hbase:meta} for each provided {@link RegionInfo}. Best effort.<a name="line.168"></a>
+<span class="sourceLineNo">169</span>   * @param masterServices used to connect to {@code hbase:meta}<a name="line.169"></a>
+<span class="sourceLineNo">170</span>   * @param newRegionInfos the new {@link RegionInfo} entries to add to the filesystem<a name="line.170"></a>
+<span class="sourceLineNo">171</span>   * @return a list of {@link RegionInfo} entries for which {@code hbase:meta} entries were<a name="line.171"></a>
+<span class="sourceLineNo">172</span>   *   successfully created<a name="line.172"></a>
+<span class="sourceLineNo">173</span>   */<a name="line.173"></a>
+<span class="sourceLineNo">174</span>  private static List&lt;RegionInfo&gt; createMetaEntries(final MasterServices masterServices,<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    final List&lt;RegionInfo&gt; newRegionInfos) {<a name="line.175"></a>
+<span class="sourceLineNo">176</span><a name="line.176"></a>
+<span class="sourceLineNo">177</span>    final List&lt;Either&lt;RegionInfo, IOException&gt;&gt; addMetaEntriesResults = newRegionInfos.stream()<a name="line.177"></a>
+<span class="sourceLineNo">178</span>      .map(regionInfo -&gt; {<a name="line.178"></a>
+<span class="sourceLineNo">179</span>        try {<a name="line.179"></a>
+<span class="sourceLineNo">180</span>          MetaTableAccessor.addRegionToMeta(masterServices.getConnection(), regionInfo);<a name="line.180"></a>
+<span class="sourceLineNo">181</span>          masterServices.getAssignmentManager()<a name="line.181"></a>
+<span class="sourceLineNo">182</span>            .getRegionStates()<a name="line.182"></a>
+<span class="sourceLineNo">183</span>            .updateRegionState(regionInfo, RegionState.State.CLOSED);<a name="line.183"></a>
+<span class="sourceLineNo">184</span>          return Either.&lt;RegionInfo, IOException&gt;ofLeft(regionInfo);<a name="line.184"></a>
+<span class="sourceLineNo">185</span>        } catch (IOException e) {<a name="line.185"></a>
+<span class="sourceLineNo">186</span>          return Either.&lt;RegionInfo, IOException&gt;ofRight(e);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>        }<a name="line.187"></a>
+<span class="sourceLineNo">188</span>      })<a name="line.188"></a>
+<span class="sourceLineNo">189</span>      .collect(Collectors.toList());<a name="line.189"></a>
+<span class="sourceLineNo">190</span>    final List&lt;RegionInfo&gt; createMetaEntriesSuccesses = addMetaEntriesResults.stream()<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      .filter(Either::hasLeft)<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      .map(Either::getLeft)<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      .collect(Collectors.toList());<a name="line.193"></a>
+<span class="sourceLineNo">194</span>    final List&lt;IOException&gt; createMetaEntriesFailures = addMetaEntriesResults.stream()<a name="line.194"></a>
+<span class="sourceLineNo">195</span>      .filter(Either::hasRight)<a name="line.195"></a>
+<span class="sourceLineNo">196</span>      .map(Either::getRight)<a name="line.196"></a>
+<span class="sourceLineNo">197</span>      .collect(Collectors.toList());<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    LOG.debug("Added {}/{} entries to hbase:meta",<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      createMetaEntriesSuccesses.size(), newRegionInfos.size());<a name="line.199"></a>
+<span class="sourceLineNo">200</span><a name="line.200"></a>
+<span class="sourceLineNo">201</span>    if (!createMetaEntriesFailures.isEmpty()) {<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      LOG.warn("Failed to create entries in hbase:meta for {}/{} RegionInfo descriptors. First"<a name="line.202"></a>
+<span class="sourceLineNo">203</span>          + " failure message included; full list of failures with accompanying stack traces is"<a name="line.203"></a>
+<span class="sourceLineNo">204</span>          + " available at log level DEBUG. message={}", createMetaEntriesFailures.size(),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>        addMetaEntriesResults.size(), createMetaEntriesFailures.get(0).getMessage());<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      if (LOG.isDebugEnabled()) {<a name="line.206"></a>
+<span class="sourceLineNo">207</span>        createMetaEntriesFailures.forEach(<a name="line.207"></a>
+<span class="sourceLineNo">208</span>          ioe -&gt; LOG.debug("Attempt to fix region hole in hbase:meta failed.", ioe));<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      }<a name="line.209"></a>
+<span class="sourceLineNo">210</span>    }<a name="line.210"></a>
+<span class="sourceLineNo">211</span><a name="line.211"></a>
+<span class="sourceLineNo">212</span>    return createMetaEntriesSuccesses;<a name="line.212"></a>
+<span class="sourceLineNo">213</span>  }<a name="line.213"></a>
+<span class="sourceLineNo">214</span><a name="line.214"></a>
+<span class="sourceLineNo">215</span>  /**<a name="line.215"></a>
+<span class="sourceLineNo">216</span>   * Fix overlaps noted in CJ consistency report.<a name="line.216"></a>
+<span class="sourceLineNo">217</span>   */<a name="line.217"></a>
+<span class="sourceLineNo">218</span>  void fixOverlaps(CatalogJanitor.Report report) throws IOException {<a name="line.218"></a>
+<span class="sourceLineNo">219</span>    for (Set&lt;RegionInfo&gt; regions: calculateMerges(maxMergeCount, report.getOverlaps())) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>      RegionInfo [] regionsArray = regions.toArray(new RegionInfo [] {});<a name="line.220"></a>
+<span class="sourceLineNo">221</span>      try {<a name="line.221"></a>
+<span class="sourceLineNo">222</span>        this.masterServices.mergeRegions(regionsArray,<a name="line.222"></a>
+<span class="sourceLineNo">223</span>            true, HConstants.NO_NONCE, HConstants.NO_NONCE);<a name="line.223"></a>
+<span class="sourceLineNo">224</span>      } catch (MergeRegionException mre) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>        LOG.warn("Failed overlap fix of {}", regionsArray, mre);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>      }<a name="line.226"></a>
+<span class="sourceLineNo">227</span>    }<a name="line.227"></a>
+<span class="sourceLineNo">228</span>  }<a name="line.228"></a>
+<span class="sourceLineNo">229</span><a name="line.229"></a>
+<span class="sourceLineNo">230</span>  /**<a name="line.230"></a>
+<span class="sourceLineNo">231</span>   * Run through &lt;code&gt;overlaps&lt;/code&gt; and return a list of merges to run.<a name="line.231"></a>
+<span class="sourceLineNo">232</span>   * Presumes overlaps are ordered (which they are coming out of the CatalogJanitor<a name="line.232"></a>
+<span class="sourceLineNo">233</span>   * consistency report).<a name="line.233"></a>
+<span class="sourceLineNo">234</span>   * @param maxMergeCount Maximum regions to merge at a time (avoid merging<a name="line.234"></a>
+<span class="sourceLineNo">235</span>   *   100k regions in one go!)<a name="line.235"></a>
+<span class="sourceLineNo">236</span>   */<a name="line.236"></a>
+<span class="sourceLineNo">237</span>  @VisibleForTesting<a name="line.237"></a>
+<span class="sourceLineNo">238</span>  static List&lt;SortedSet&lt;RegionInfo&gt;&gt; calculateMerges(int maxMergeCount,<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      List&lt;Pair&lt;RegionInfo, RegionInfo&gt;&gt; overlaps) {<a name="line.239"></a>
+<span class="sourceLineNo">240</span>    if (overlaps.isEmpty()) {<a name="line.240"></a>
+<span class="sourceLineNo">241</span>      LOG.debug("No overlaps.");<a name="line.241"></a>
+<span class="sourceLineNo">242</span>      return Collections.emptyList();<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    }<a name="line.243"></a>
+<span class="sourceLineNo">244</span>    List&lt;SortedSet&lt;RegionInfo&gt;&gt; merges = new ArrayList&lt;&gt;();<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    SortedSet&lt;RegionInfo&gt; currentMergeSet = new TreeSet&lt;&gt;();<a name="line.245"></a>
+<span class="sourceLineNo">246</span>    HashSet&lt;RegionInfo&gt; regionsInMergeSet = new HashSet&lt;&gt;();<a name="line.246"></a>
+<span class="sourceLineNo">247</span>    RegionInfo regionInfoWithlargestEndKey =  null;<a name="line.247"></a>
+<span class="sourceLineNo">248</span>    for (Pair&lt;RegionInfo, RegionInfo&gt; pair: overlaps) {<a name="line.248"></a>
+<span class="sourceLineNo">249</span>      if (regionInfoWithlargestEndKey != null) {<a name="line.249"></a>
+<span class="sourceLineNo">250</span>        if (!isOverlap(regionInfoWithlargestEndKey, pair) ||<a name="line.250"></a>
+<span class="sourceLineNo">251</span>            currentMergeSet.size() &gt;= maxMergeCount) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>          // Log when we cut-off-merge because we hit the configured maximum merge limit.<a name="line.252"></a>
+<span class="sourceLineNo">253</span>          if (currentMergeSet.size() &gt;= maxMergeCount) {<a name="line.253"></a>
+<span class="sourceLineNo">254</span>            LOG.warn("Ran into maximum-at-a-time merges limit={}", maxMergeCount);<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>          // In the case of the merge set contains only 1 region or empty, it does not need to<a name="line.257"></a>
+<span class="sourceLineNo">258</span>          // submit this merge request as no merge is going to happen. currentMergeSet can be<a name="line.258"></a>
+<span class="sourceLineNo">259</span>          // reused in this case.<a name="line.259"></a>
+<span class="sourceLineNo">260</span>          if (currentMergeSet.size() &lt;= 1) {<a name="line.260"></a>
+<span class="sourceLineNo">261</span>            for (RegionInfo ri : currentMergeSet) {<a name="line.261"></a>
+<span class="sourceLineNo">262</span>              regionsInMergeSet.remove(ri);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>            }<a name="line.263"></a>
+<span class="sourceLineNo">264</span>            currentMergeSet.clear();<a name="line.264"></a>
+<span class="sourceLineNo">265</span>          } else {<a name="line.265"></a>
+<span class="sourceLineNo">266</span>            merges.add(currentMergeSet);<a name="line.266"></a>
+<span class="sourceLineNo">267</span>            currentMergeSet = new TreeSet&lt;&gt;();<a name="line.267"></a>
+<span class="sourceLineNo">268</span>          }<a name="line.268"></a>
+<span class="sourceLineNo">269</span>        }<a name="line.269"></a>
+<span class="sourceLineNo">270</span>      }<a name="line.270"></a>
+<span class="sourceLineNo">271</span><a name="line.271"></a>
+<span class="sourceLineNo">272</span>      // Do not add the same region into multiple merge set, this will fail<a name="line.272"></a>
+<span class="sourceLineNo">273</span>      // the second merge request.<a name="line.273"></a>
+<span class="sourceLineNo">274</span>      if (!regionsInMergeSet.contains(pair.getFirst())) {<a name="line.274"></a>
+<span class="sourceLineNo">275</span>        currentMergeSet.add(pair.getFirst());<a name="line.275"></a>
+<span class="sourceLineNo">276</span>        regionsInMergeSet.add(pair.getFirst());<a name="line.276"></a>
+<span class="sourceLineNo">277</span>      }<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (!regionsInMergeSet.contains(pair.getSecond())) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        currentMergeSet.add(pair.getSecond());<a name="line.279"></a>
+<span class="sourceLineNo">280</span>        regionsInMergeSet.add(pair.getSecond());<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>      regionInfoWithlargestEndKey = getRegionInfoWithLargestEndKey(<a name="line.283"></a>
+<span class="sourceLineNo">284</span>        getRegionInfoWithLargestEndKey(pair.getFirst(), pair.getSecond()),<a name="line.284"></a>
+<span class="sourceLineNo">285</span>          regionInfoWithlargestEndKey);<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span>    merges.add(currentMergeSet);<a name="line.287"></a>
+<span class="sourceLineNo">288</span>    return merges;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>  }<a name="line.289"></a>
+<span class="sourceLineNo">290</span><a name="line.290"></a>
+<span class="sourceLineNo">291</span>  /**<a name="line.291"></a>
+<span class="sourceLineNo">292</span>   * @return Either &lt;code&gt;a&lt;/code&gt; or &lt;code&gt;b&lt;/code&gt;, whichever has the<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   *   endkey that is furthest along in the Table.<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
+<span class="sourceLineNo">295</span>  @VisibleForTesting<a name="line.295"></a>
+<span class="sourceLineNo">296</span>  static RegionInfo getRegionInfoWithLargestEndKey(RegionInfo a, RegionInfo b) {<a name="line.296"></a>
+<span class="sourceLineNo">297</span>    if (a == null) {<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      // b may be null.<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      return b;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>    }<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    if (b == null) {<a name="line.301"></a>
+<span class="sourceLineNo">302</span>      // Both are null. The return is not-defined.<a name="line.302"></a>
+<span class="sourceLineNo">303</span>      return a;<a name="line.303"></a>
+<span class="sourceLineNo">304</span>    }<a name="line.304"></a>
+<span class="sourceLineNo">305</span>    if (!a.getTable().equals(b.getTable())) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>      // This is an odd one. This should be the right answer.<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      return b;<a name="line.307"></a>
+<span class="sourceLineNo">308</span>    }<a name="line.308"></a>
+<span class="sourceLineNo">309</span>    if (a.isLast()) {<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return a;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    if (b.isLast()) {<a name="line.312"></a>
+<span class="sourceLineNo">313</span>      return b;<a name="line.313"></a>
+<span class="sourceLineNo">314</span>    }<a name="line.314"></a>
+<span class="sourceLineNo">315</span>    int compare = Bytes.compareTo(a.getEndKey(), b.getEndKey());<a name="line.315"></a>
+<span class="sourceLineNo">316</span>    return compare == 0 || compare &gt; 0? a: b;<a name="line.316"></a>
+<span class="sourceLineNo">317</span>  }<a name="line.317"></a>
+<span class="sourceLineNo">318</span><a name="line.318"></a>
+<span class="sourceLineNo">319</span>  /**<a name="line.319"></a>
+<span class="sourceLineNo">320</span>   * @return True if an overlap found between passed in &lt;code&gt;ri&lt;/code&gt; and<a name="line.320"></a>
+<span class="sourceLineNo">321</span>   *   the &lt;code&gt;pair&lt;/code&gt;. Does NOT check the pairs themselves overlap.<a name="line.321"></a>
+<span class="sourceLineNo">322</span>   */<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
+<span class="sourceLineNo">324</span>  static boolean isOverlap(RegionInfo ri, Pair&lt;RegionInfo, RegionInfo&gt; pair) {<a name="line.324"></a>
+<span class="sourceLineNo">325</span>    if (ri == null || pair == null) {<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      // Can't be an overlap in either of these cases.<a name="line.326"></a>
+<span class="sourceLineNo">327</span>      return false;<a name="line.327"></a>
+<span class="sourceLineNo">328</span>    }<a name="line.328"></a>
+<span class="sourceLineNo">329</span>    return ri.isOverlap(pair.getFirst()) || ri.isOverlap(pair.getSecond());<a name="line.329"></a>
+<span class="sourceLineNo">330</span>  }<a name="line.330"></a>
+<span class="sourceLineNo">331</span><a name="line.331"></a>
+<span class="sourceLineNo">332</span>  /**<a name="line.332"></a>
+<span class="sourceLineNo">333</span>   * A union over {@link L} and {@link R}.<a name="line.333"></a>
+<span class="sourceLineNo">334</span>   */<a name="line.334"></a>
+<span class="sourceLineNo">335</span>  private static class Either&lt;L, R&gt; {<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    private final L left;<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    private final R right;<a name="line.337"></a>
+<span class="sourceLineNo">338</span><a name="line.338"></a>
+<span class="sourceLineNo">339</span>    public static &lt;L, R&gt; Either&lt;L, R&gt; ofLeft(L left) {<a name="line.339"></a>
+<span class="sourceLineNo">340</span>      return new Either&lt;&gt;(left, null);<a name="line.340"></a>
+<span class="sourceLineNo">341</span>    }<a name="line.341"></a>
+<span class="sourceLineNo">342</span><a name="line.342"></a>
+<span class="sourceLineNo">343</span>    public static &lt;L, R&gt; Either&lt;L, R&gt; ofRight(R right) {<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      return new Either&lt;&gt;(null, right);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    }<a name="line.345"></a>
+<span class="sourceLineNo">346</span><a name="line.346"></a>
+<span class="sourceLineNo">347</span>    Either(L left, R right) {<a name="line.347"></a>
+<span class="sourceLineNo">348</span>      this.left = left;<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      this.right = right;<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    }<a name="line.350"></a>
+<span class="sourceLineNo">351</span><a name="line.351"></a>
+<span class="sourceLineNo">352</span>    public boolean hasLeft() {<a name="line.352"></a>
+<span class="sourceLineNo">353</span>      return left != null;<a name="line.353"></a>
+<span class="sourceLineNo">354</span>    }<a name="line.354"></a>
+<span class="sourceLineNo">355</span><a name="line.355"></a>
+<span class="sourceLineNo">356</span>    public L getLeft() {<a name="line.356"></a>
+<span class="sourceLineNo">357</span>      if (!hasLeft()) {<a name="line.357"></a>
+<span class="sourceLineNo">358</span>        throw new IllegalStateException("Either contains no left.");<a name="line.358"></a>
+<span class="sourceLineNo">359</span>      }<a name="line.359"></a>
+<span class="sourceLineNo">360</span>      return left;<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>    public boolean hasRight() {<a name="line.363"></a>
+<span class="sourceLineNo">364</span>      return right != null;<a name="line.364"></a>
+<span class="sourceLineNo">365</span>    }<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    public R getRight() {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      if (!hasRight()) {<a name="line.368"></a>
+<span class="sourceLineNo">369</span>        throw new IllegalStateException("Either contains no right.");<a name="line.369"></a>
+<span class="sourceLineNo">370</span>      }<a name="line.370"></a>
+<span class="sourceLineNo">371</span>      return right;<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>}<a name="line.374"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/MetaFixer.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/MetaFixer.html
index b671ca9..594c720 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/MetaFixer.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/MetaFixer.html
@@ -28,335 +28,358 @@
 <span class="sourceLineNo">020</span>import java.io.IOException;<a name="line.20"></a>
 <span class="sourceLineNo">021</span>import java.util.ArrayList;<a name="line.21"></a>
 <span class="sourceLineNo">022</span>import java.util.Collections;<a name="line.22"></a>
-<span class="sourceLineNo">023</span>import java.util.List;<a name="line.23"></a>
-<span class="sourceLineNo">024</span>import java.util.Optional;<a name="line.24"></a>
-<span class="sourceLineNo">025</span>import java.util.Set;<a name="line.25"></a>
-<span class="sourceLineNo">026</span>import java.util.SortedSet;<a name="line.26"></a>
-<span class="sourceLineNo">027</span>import java.util.TreeSet;<a name="line.27"></a>
-<span class="sourceLineNo">028</span>import java.util.stream.Collectors;<a name="line.28"></a>
-<span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.HConstants;<a name="line.29"></a>
-<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.MetaTableAccessor;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.TableName;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.client.RegionInfoBuilder;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.exceptions.MergeRegionException;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.master.assignment.TransitRegionStateProcedure;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import org.apache.hadoop.hbase.util.Pair;<a name="line.37"></a>
-<span class="sourceLineNo">038</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.38"></a>
-<span class="sourceLineNo">039</span>import org.slf4j.Logger;<a name="line.39"></a>
-<span class="sourceLineNo">040</span>import org.slf4j.LoggerFactory;<a name="line.40"></a>
-<span class="sourceLineNo">041</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.41"></a>
-<span class="sourceLineNo">042</span><a name="line.42"></a>
+<span class="sourceLineNo">023</span>import java.util.HashSet;<a name="line.23"></a>
+<span class="sourceLineNo">024</span>import java.util.List;<a name="line.24"></a>
+<span class="sourceLineNo">025</span>import java.util.Optional;<a name="line.25"></a>
+<span class="sourceLineNo">026</span>import java.util.Set;<a name="line.26"></a>
+<span class="sourceLineNo">027</span>import java.util.SortedSet;<a name="line.27"></a>
+<span class="sourceLineNo">028</span>import java.util.TreeSet;<a name="line.28"></a>
+<span class="sourceLineNo">029</span>import java.util.stream.Collectors;<a name="line.29"></a>
+<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.HConstants;<a name="line.30"></a>
+<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.MetaTableAccessor;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.TableName;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.client.RegionInfoBuilder;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.exceptions.MergeRegionException;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.master.assignment.TransitRegionStateProcedure;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import org.apache.hadoop.hbase.util.Pair;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.39"></a>
+<span class="sourceLineNo">040</span>import org.slf4j.Logger;<a name="line.40"></a>
+<span class="sourceLineNo">041</span>import org.slf4j.LoggerFactory;<a name="line.41"></a>
+<span class="sourceLineNo">042</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.42"></a>
 <span class="sourceLineNo">043</span><a name="line.43"></a>
-<span class="sourceLineNo">044</span>/**<a name="line.44"></a>
-<span class="sourceLineNo">045</span> * Server-side fixing of bad or inconsistent state in hbase:meta.<a name="line.45"></a>
-<span class="sourceLineNo">046</span> * Distinct from MetaTableAccessor because {@link MetaTableAccessor} is about low-level<a name="line.46"></a>
-<span class="sourceLineNo">047</span> * manipulations driven by the Master. This class MetaFixer is<a name="line.47"></a>
-<span class="sourceLineNo">048</span> * employed by the Master and it 'knows' about holes and orphans<a name="line.48"></a>
-<span class="sourceLineNo">049</span> * and encapsulates their fixing on behalf of the Master.<a name="line.49"></a>
-<span class="sourceLineNo">050</span> */<a name="line.50"></a>
-<span class="sourceLineNo">051</span>@InterfaceAudience.Private<a name="line.51"></a>
-<span class="sourceLineNo">052</span>class MetaFixer {<a name="line.52"></a>
-<span class="sourceLineNo">053</span>  private static final Logger LOG = LoggerFactory.getLogger(MetaFixer.class);<a name="line.53"></a>
-<span class="sourceLineNo">054</span>  private static final String MAX_MERGE_COUNT_KEY = "hbase.master.metafixer.max.merge.count";<a name="line.54"></a>
-<span class="sourceLineNo">055</span>  private static final int MAX_MERGE_COUNT_DEFAULT = 64;<a name="line.55"></a>
-<span class="sourceLineNo">056</span><a name="line.56"></a>
-<span class="sourceLineNo">057</span>  private final MasterServices masterServices;<a name="line.57"></a>
-<span class="sourceLineNo">058</span>  /**<a name="line.58"></a>
-<span class="sourceLineNo">059</span>   * Maximum for many regions to merge at a time.<a name="line.59"></a>
-<span class="sourceLineNo">060</span>   */<a name="line.60"></a>
-<span class="sourceLineNo">061</span>  private final int maxMergeCount;<a name="line.61"></a>
-<span class="sourceLineNo">062</span><a name="line.62"></a>
-<span class="sourceLineNo">063</span>  MetaFixer(MasterServices masterServices) {<a name="line.63"></a>
-<span class="sourceLineNo">064</span>    this.masterServices = masterServices;<a name="line.64"></a>
-<span class="sourceLineNo">065</span>    this.maxMergeCount = this.masterServices.getConfiguration().<a name="line.65"></a>
-<span class="sourceLineNo">066</span>      getInt(MAX_MERGE_COUNT_KEY, MAX_MERGE_COUNT_DEFAULT);<a name="line.66"></a>
-<span class="sourceLineNo">067</span>  }<a name="line.67"></a>
-<span class="sourceLineNo">068</span><a name="line.68"></a>
-<span class="sourceLineNo">069</span>  void fix() throws IOException {<a name="line.69"></a>
-<span class="sourceLineNo">070</span>    CatalogJanitor.Report report = this.masterServices.getCatalogJanitor().getLastReport();<a name="line.70"></a>
-<span class="sourceLineNo">071</span>    if (report == null) {<a name="line.71"></a>
-<span class="sourceLineNo">072</span>      LOG.info("CatalogJanitor has not generated a report yet; run 'catalogjanitor_run' in " +<a name="line.72"></a>
-<span class="sourceLineNo">073</span>          "shell or wait until CatalogJanitor chore runs.");<a name="line.73"></a>
-<span class="sourceLineNo">074</span>      return;<a name="line.74"></a>
-<span class="sourceLineNo">075</span>    }<a name="line.75"></a>
-<span class="sourceLineNo">076</span>    fixHoles(report);<a name="line.76"></a>
-<span class="sourceLineNo">077</span>    fixOverlaps(report);<a name="line.77"></a>
-<span class="sourceLineNo">078</span>    // Run the ReplicationBarrierCleaner here; it may clear out rep_barrier rows which<a name="line.78"></a>
-<span class="sourceLineNo">079</span>    // can help cleaning up damaged hbase:meta.<a name="line.79"></a>
-<span class="sourceLineNo">080</span>    this.masterServices.runReplicationBarrierCleaner();<a name="line.80"></a>
-<span class="sourceLineNo">081</span>  }<a name="line.81"></a>
-<span class="sourceLineNo">082</span><a name="line.82"></a>
-<span class="sourceLineNo">083</span>  /**<a name="line.83"></a>
-<span class="sourceLineNo">084</span>   * If hole, it papers it over by adding a region in the filesystem and to hbase:meta.<a name="line.84"></a>
-<span class="sourceLineNo">085</span>   * Does not assign.<a name="line.85"></a>
-<span class="sourceLineNo">086</span>   */<a name="line.86"></a>
-<span class="sourceLineNo">087</span>  void fixHoles(CatalogJanitor.Report report) {<a name="line.87"></a>
-<span class="sourceLineNo">088</span>    final List&lt;Pair&lt;RegionInfo, RegionInfo&gt;&gt; holes = report.getHoles();<a name="line.88"></a>
-<span class="sourceLineNo">089</span>    if (holes.isEmpty()) {<a name="line.89"></a>
-<span class="sourceLineNo">090</span>      LOG.info("CatalogJanitor Report contains no holes to fix. Skipping.");<a name="line.90"></a>
-<span class="sourceLineNo">091</span>      return;<a name="line.91"></a>
-<span class="sourceLineNo">092</span>    }<a name="line.92"></a>
-<span class="sourceLineNo">093</span><a name="line.93"></a>
-<span class="sourceLineNo">094</span>    LOG.info("Identified {} region holes to fix. Detailed fixup progress logged at DEBUG.",<a name="line.94"></a>
-<span class="sourceLineNo">095</span>      holes.size());<a name="line.95"></a>
-<span class="sourceLineNo">096</span><a name="line.96"></a>
-<span class="sourceLineNo">097</span>    final List&lt;RegionInfo&gt; newRegionInfos = createRegionInfosForHoles(holes);<a name="line.97"></a>
-<span class="sourceLineNo">098</span>    final List&lt;RegionInfo&gt; newMetaEntries = createMetaEntries(masterServices, newRegionInfos);<a name="line.98"></a>
-<span class="sourceLineNo">099</span>    final TransitRegionStateProcedure[] assignProcedures = masterServices<a name="line.99"></a>
-<span class="sourceLineNo">100</span>      .getAssignmentManager()<a name="line.100"></a>
-<span class="sourceLineNo">101</span>      .createRoundRobinAssignProcedures(newMetaEntries);<a name="line.101"></a>
-<span class="sourceLineNo">102</span><a name="line.102"></a>
-<span class="sourceLineNo">103</span>    masterServices.getMasterProcedureExecutor().submitProcedures(assignProcedures);<a name="line.103"></a>
-<span class="sourceLineNo">104</span>    LOG.info(<a name="line.104"></a>
-<span class="sourceLineNo">105</span>      "Scheduled {}/{} new regions for assignment.", assignProcedures.length, holes.size());<a name="line.105"></a>
-<span class="sourceLineNo">106</span>  }<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>   * Create a new {@link RegionInfo} corresponding to each provided "hole" pair.<a name="line.109"></a>
-<span class="sourceLineNo">110</span>   */<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  private static List&lt;RegionInfo&gt; createRegionInfosForHoles(<a name="line.111"></a>
-<span class="sourceLineNo">112</span>    final List&lt;Pair&lt;RegionInfo, RegionInfo&gt;&gt; holes) {<a name="line.112"></a>
-<span class="sourceLineNo">113</span>    final List&lt;RegionInfo&gt; newRegionInfos = holes.stream()<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      .map(MetaFixer::getHoleCover)<a name="line.114"></a>
-<span class="sourceLineNo">115</span>      .filter(Optional::isPresent)<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      .map(Optional::get)<a name="line.116"></a>
-<span class="sourceLineNo">117</span>      .collect(Collectors.toList());<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    LOG.debug("Constructed {}/{} RegionInfo descriptors corresponding to identified holes.",<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      newRegionInfos.size(), holes.size());<a name="line.119"></a>
-<span class="sourceLineNo">120</span>    return newRegionInfos;<a name="line.120"></a>
-<span class="sourceLineNo">121</span>  }<a name="line.121"></a>
-<span class="sourceLineNo">122</span><a name="line.122"></a>
-<span class="sourceLineNo">123</span>  /**<a name="line.123"></a>
-<span class="sourceLineNo">124</span>   * @return Attempts to calculate a new {@link RegionInfo} that covers the region range described<a name="line.124"></a>
-<span class="sourceLineNo">125</span>   *   in {@code hole}.<a name="line.125"></a>
-<span class="sourceLineNo">126</span>   */<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private static Optional&lt;RegionInfo&gt; getHoleCover(Pair&lt;RegionInfo, RegionInfo&gt; hole) {<a name="line.127"></a>
-<span class="sourceLineNo">128</span>    final RegionInfo left = hole.getFirst();<a name="line.128"></a>
-<span class="sourceLineNo">129</span>    final RegionInfo right = hole.getSecond();<a name="line.129"></a>
-<span class="sourceLineNo">130</span><a name="line.130"></a>
-<span class="sourceLineNo">131</span>    if (left.getTable().equals(right.getTable())) {<a name="line.131"></a>
-<span class="sourceLineNo">132</span>      // Simple case.<a name="line.132"></a>
-<span class="sourceLineNo">133</span>      if (Bytes.compareTo(left.getEndKey(), right.getStartKey()) &gt;= 0) {<a name="line.133"></a>
-<span class="sourceLineNo">134</span>        LOG.warn("Skipping hole fix; left-side endKey is not less than right-side startKey;"<a name="line.134"></a>
-<span class="sourceLineNo">135</span>          + " left=&lt;{}&gt;, right=&lt;{}&gt;", left, right);<a name="line.135"></a>
-<span class="sourceLineNo">136</span>        return Optional.empty();<a name="line.136"></a>
-<span class="sourceLineNo">137</span>      }<a name="line.137"></a>
-<span class="sourceLineNo">138</span>      return Optional.of(buildRegionInfo(left.getTable(), left.getEndKey(), right.getStartKey()));<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>    final boolean leftUndefined = left.equals(RegionInfo.UNDEFINED);<a name="line.141"></a>
-<span class="sourceLineNo">142</span>    final boolean rightUndefined = right.equals(RegionInfo.UNDEFINED);<a name="line.142"></a>
-<span class="sourceLineNo">143</span>    final boolean last = left.isLast();<a name="line.143"></a>
-<span class="sourceLineNo">144</span>    final boolean first = right.isFirst();<a name="line.144"></a>
-<span class="sourceLineNo">145</span>    if (leftUndefined &amp;&amp; rightUndefined) {<a name="line.145"></a>
-<span class="sourceLineNo">146</span>      LOG.warn("Skipping hole fix; both the hole left-side and right-side RegionInfos are " +<a name="line.146"></a>
-<span class="sourceLineNo">147</span>        "UNDEFINED; left=&lt;{}&gt;, right=&lt;{}&gt;", left, right);<a name="line.147"></a>
-<span class="sourceLineNo">148</span>      return Optional.empty();<a name="line.148"></a>
-<span class="sourceLineNo">149</span>    }<a name="line.149"></a>
-<span class="sourceLineNo">150</span>    if (leftUndefined || last) {<a name="line.150"></a>
-<span class="sourceLineNo">151</span>      return Optional.of(<a name="line.151"></a>
-<span class="sourceLineNo">152</span>        buildRegionInfo(right.getTable(), HConstants.EMPTY_START_ROW, right.getStartKey()));<a name="line.152"></a>
-<span class="sourceLineNo">153</span>    }<a name="line.153"></a>
-<span class="sourceLineNo">154</span>    if (rightUndefined || first) {<a name="line.154"></a>
-<span class="sourceLineNo">155</span>      return Optional.of(<a name="line.155"></a>
-<span class="sourceLineNo">156</span>        buildRegionInfo(left.getTable(), left.getEndKey(), HConstants.EMPTY_END_ROW));<a name="line.156"></a>
-<span class="sourceLineNo">157</span>    }<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    LOG.warn("Skipping hole fix; don't know what to do with left=&lt;{}&gt;, right=&lt;{}&gt;", left, right);<a name="line.158"></a>
-<span class="sourceLineNo">159</span>    return Optional.empty();<a name="line.159"></a>
-<span class="sourceLineNo">160</span>  }<a name="line.160"></a>
-<span class="sourceLineNo">161</span><a name="line.161"></a>
-<span class="sourceLineNo">162</span>  private static RegionInfo buildRegionInfo(TableName tn, byte [] start, byte [] end) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    return RegionInfoBuilder.newBuilder(tn).setStartKey(start).setEndKey(end).build();<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  /**<a name="line.166"></a>
-<span class="sourceLineNo">167</span>   * Create entries in the {@code hbase:meta} for each provided {@link RegionInfo}. Best effort.<a name="line.167"></a>
-<span class="sourceLineNo">168</span>   * @param masterServices used to connect to {@code hbase:meta}<a name="line.168"></a>
-<span class="sourceLineNo">169</span>   * @param newRegionInfos the new {@link RegionInfo} entries to add to the filesystem<a name="line.169"></a>
-<span class="sourceLineNo">170</span>   * @return a list of {@link RegionInfo} entries for which {@code hbase:meta} entries were<a name="line.170"></a>
-<span class="sourceLineNo">171</span>   *   successfully created<a name="line.171"></a>
-<span class="sourceLineNo">172</span>   */<a name="line.172"></a>
-<span class="sourceLineNo">173</span>  private static List&lt;RegionInfo&gt; createMetaEntries(final MasterServices masterServices,<a name="line.173"></a>
-<span class="sourceLineNo">174</span>    final List&lt;RegionInfo&gt; newRegionInfos) {<a name="line.174"></a>
-<span class="sourceLineNo">175</span><a name="line.175"></a>
-<span class="sourceLineNo">176</span>    final List&lt;Either&lt;RegionInfo, IOException&gt;&gt; addMetaEntriesResults = newRegionInfos.stream()<a name="line.176"></a>
-<span class="sourceLineNo">177</span>      .map(regionInfo -&gt; {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>        try {<a name="line.178"></a>
-<span class="sourceLineNo">179</span>          MetaTableAccessor.addRegionToMeta(masterServices.getConnection(), regionInfo);<a name="line.179"></a>
-<span class="sourceLineNo">180</span>          masterServices.getAssignmentManager()<a name="line.180"></a>
-<span class="sourceLineNo">181</span>            .getRegionStates()<a name="line.181"></a>
-<span class="sourceLineNo">182</span>            .updateRegionState(regionInfo, RegionState.State.CLOSED);<a name="line.182"></a>
-<span class="sourceLineNo">183</span>          return Either.&lt;RegionInfo, IOException&gt;ofLeft(regionInfo);<a name="line.183"></a>
-<span class="sourceLineNo">184</span>        } catch (IOException e) {<a name="line.184"></a>
-<span class="sourceLineNo">185</span>          return Either.&lt;RegionInfo, IOException&gt;ofRight(e);<a name="line.185"></a>
-<span class="sourceLineNo">186</span>        }<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      })<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      .collect(Collectors.toList());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    final List&lt;RegionInfo&gt; createMetaEntriesSuccesses = addMetaEntriesResults.stream()<a name="line.189"></a>
-<span class="sourceLineNo">190</span>      .filter(Either::hasLeft)<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      .map(Either::getLeft)<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      .collect(Collectors.toList());<a name="line.192"></a>
-<span class="sourceLineNo">193</span>    final List&lt;IOException&gt; createMetaEntriesFailures = addMetaEntriesResults.stream()<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      .filter(Either::hasRight)<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      .map(Either::getRight)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>      .collect(Collectors.toList());<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    LOG.debug("Added {}/{} entries to hbase:meta",<a name="line.197"></a>
-<span class="sourceLineNo">198</span>      createMetaEntriesSuccesses.size(), newRegionInfos.size());<a name="line.198"></a>
-<span class="sourceLineNo">199</span><a name="line.199"></a>
-<span class="sourceLineNo">200</span>    if (!createMetaEntriesFailures.isEmpty()) {<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      LOG.warn("Failed to create entries in hbase:meta for {}/{} RegionInfo descriptors. First"<a name="line.201"></a>
-<span class="sourceLineNo">202</span>          + " failure message included; full list of failures with accompanying stack traces is"<a name="line.202"></a>
-<span class="sourceLineNo">203</span>          + " available at log level DEBUG. message={}", createMetaEntriesFailures.size(),<a name="line.203"></a>
-<span class="sourceLineNo">204</span>        addMetaEntriesResults.size(), createMetaEntriesFailures.get(0).getMessage());<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      if (LOG.isDebugEnabled()) {<a name="line.205"></a>
-<span class="sourceLineNo">206</span>        createMetaEntriesFailures.forEach(<a name="line.206"></a>
-<span class="sourceLineNo">207</span>          ioe -&gt; LOG.debug("Attempt to fix region hole in hbase:meta failed.", ioe));<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      }<a name="line.208"></a>
-<span class="sourceLineNo">209</span>    }<a name="line.209"></a>
-<span class="sourceLineNo">210</span><a name="line.210"></a>
-<span class="sourceLineNo">211</span>    return createMetaEntriesSuccesses;<a name="line.211"></a>
-<span class="sourceLineNo">212</span>  }<a name="line.212"></a>
-<span class="sourceLineNo">213</span><a name="line.213"></a>
-<span class="sourceLineNo">214</span>  /**<a name="line.214"></a>
-<span class="sourceLineNo">215</span>   * Fix overlaps noted in CJ consistency report.<a name="line.215"></a>
-<span class="sourceLineNo">216</span>   */<a name="line.216"></a>
-<span class="sourceLineNo">217</span>  void fixOverlaps(CatalogJanitor.Report report) throws IOException {<a name="line.217"></a>
-<span class="sourceLineNo">218</span>    for (Set&lt;RegionInfo&gt; regions: calculateMerges(maxMergeCount, report.getOverlaps())) {<a name="line.218"></a>
-<span class="sourceLineNo">219</span>      RegionInfo [] regionsArray = regions.toArray(new RegionInfo [] {});<a name="line.219"></a>
-<span class="sourceLineNo">220</span>      try {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>        this.masterServices.mergeRegions(regionsArray,<a name="line.221"></a>
-<span class="sourceLineNo">222</span>            true, HConstants.NO_NONCE, HConstants.NO_NONCE);<a name="line.222"></a>
-<span class="sourceLineNo">223</span>      } catch (MergeRegionException mre) {<a name="line.223"></a>
-<span class="sourceLineNo">224</span>        LOG.warn("Failed overlap fix of {}", regionsArray, mre);<a name="line.224"></a>
-<span class="sourceLineNo">225</span>      }<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    }<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  /**<a name="line.229"></a>
-<span class="sourceLineNo">230</span>   * Run through &lt;code&gt;overlaps&lt;/code&gt; and return a list of merges to run.<a name="line.230"></a>
-<span class="sourceLineNo">231</span>   * Presumes overlaps are ordered (which they are coming out of the CatalogJanitor<a name="line.231"></a>
-<span class="sourceLineNo">232</span>   * consistency report).<a name="line.232"></a>
-<span class="sourceLineNo">233</span>   * @param maxMergeCount Maximum regions to merge at a time (avoid merging<a name="line.233"></a>
-<span class="sourceLineNo">234</span>   *   100k regions in one go!)<a name="line.234"></a>
-<span class="sourceLineNo">235</span>   */<a name="line.235"></a>
-<span class="sourceLineNo">236</span>  @VisibleForTesting<a name="line.236"></a>
-<span class="sourceLineNo">237</span>  static List&lt;SortedSet&lt;RegionInfo&gt;&gt; calculateMerges(int maxMergeCount,<a name="line.237"></a>
-<span class="sourceLineNo">238</span>      List&lt;Pair&lt;RegionInfo, RegionInfo&gt;&gt; overlaps) {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>    if (overlaps.isEmpty()) {<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      LOG.debug("No overlaps.");<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      return Collections.emptyList();<a name="line.241"></a>
-<span class="sourceLineNo">242</span>    }<a name="line.242"></a>
-<span class="sourceLineNo">243</span>    List&lt;SortedSet&lt;RegionInfo&gt;&gt; merges = new ArrayList&lt;&gt;();<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    SortedSet&lt;RegionInfo&gt; currentMergeSet = new TreeSet&lt;&gt;();<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    RegionInfo regionInfoWithlargestEndKey =  null;<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    for (Pair&lt;RegionInfo, RegionInfo&gt; pair: overlaps) {<a name="line.246"></a>
-<span class="sourceLineNo">247</span>      if (regionInfoWithlargestEndKey != null) {<a name="line.247"></a>
-<span class="sourceLineNo">248</span>        if (!isOverlap(regionInfoWithlargestEndKey, pair) ||<a name="line.248"></a>
-<span class="sourceLineNo">249</span>            currentMergeSet.size() &gt;= maxMergeCount) {<a name="line.249"></a>
-<span class="sourceLineNo">250</span>          // Log when we cut-off-merge because we hit the configured maximum merge limit.<a name="line.250"></a>
-<span class="sourceLineNo">251</span>          if (currentMergeSet.size() &gt;= maxMergeCount) {<a name="line.251"></a>
-<span class="sourceLineNo">252</span>            LOG.warn("Ran into maximum-at-a-time merges limit={}", maxMergeCount);<a name="line.252"></a>
-<span class="sourceLineNo">253</span>          }<a name="line.253"></a>
-<span class="sourceLineNo">254</span>          merges.add(currentMergeSet);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>          currentMergeSet = new TreeSet&lt;&gt;();<a name="line.255"></a>
-<span class="sourceLineNo">256</span>        }<a name="line.256"></a>
-<span class="sourceLineNo">257</span>      }<a name="line.257"></a>
-<span class="sourceLineNo">258</span>      currentMergeSet.add(pair.getFirst());<a name="line.258"></a>
-<span class="sourceLineNo">259</span>      currentMergeSet.add(pair.getSecond());<a name="line.259"></a>
-<span class="sourceLineNo">260</span>      regionInfoWithlargestEndKey = getRegionInfoWithLargestEndKey(<a name="line.260"></a>
-<span class="sourceLineNo">261</span>        getRegionInfoWithLargestEndKey(pair.getFirst(), pair.getSecond()),<a name="line.261"></a>
-<span class="sourceLineNo">262</span>          regionInfoWithlargestEndKey);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    }<a name="line.263"></a>
-<span class="sourceLineNo">264</span>    merges.add(currentMergeSet);<a name="line.264"></a>
-<span class="sourceLineNo">265</span>    return merges;<a name="line.265"></a>
-<span class="sourceLineNo">266</span>  }<a name="line.266"></a>
-<span class="sourceLineNo">267</span><a name="line.267"></a>
-<span class="sourceLineNo">268</span>  /**<a name="line.268"></a>
-<span class="sourceLineNo">269</span>   * @return Either &lt;code&gt;a&lt;/code&gt; or &lt;code&gt;b&lt;/code&gt;, whichever has the<a name="line.269"></a>
-<span class="sourceLineNo">270</span>   *   endkey that is furthest along in the Table.<a name="line.270"></a>
-<span class="sourceLineNo">271</span>   */<a name="line.271"></a>
-<span class="sourceLineNo">272</span>  @VisibleForTesting<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  static RegionInfo getRegionInfoWithLargestEndKey(RegionInfo a, RegionInfo b) {<a name="line.273"></a>
-<span class="sourceLineNo">274</span>    if (a == null) {<a name="line.274"></a>
-<span class="sourceLineNo">275</span>      // b may be null.<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      return b;<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    }<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (b == null) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      // Both are null. The return is not-defined.<a name="line.279"></a>
-<span class="sourceLineNo">280</span>      return a;<a name="line.280"></a>
-<span class="sourceLineNo">281</span>    }<a name="line.281"></a>
-<span class="sourceLineNo">282</span>    if (!a.getTable().equals(b.getTable())) {<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      // This is an odd one. This should be the right answer.<a name="line.283"></a>
-<span class="sourceLineNo">284</span>      return b;<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    }<a name="line.285"></a>
-<span class="sourceLineNo">286</span>    if (a.isLast()) {<a name="line.286"></a>
-<span class="sourceLineNo">287</span>      return a;<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    }<a name="line.288"></a>
-<span class="sourceLineNo">289</span>    if (b.isLast()) {<a name="line.289"></a>
-<span class="sourceLineNo">290</span>      return b;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    }<a name="line.291"></a>
-<span class="sourceLineNo">292</span>    int compare = Bytes.compareTo(a.getEndKey(), b.getEndKey());<a name="line.292"></a>
-<span class="sourceLineNo">293</span>    return compare == 0 || compare &gt; 0? a: b;<a name="line.293"></a>
-<span class="sourceLineNo">294</span>  }<a name="line.294"></a>
-<span class="sourceLineNo">295</span><a name="line.295"></a>
-<span class="sourceLineNo">296</span>  /**<a name="line.296"></a>
-<span class="sourceLineNo">297</span>   * @return True if an overlap found between passed in &lt;code&gt;ri&lt;/code&gt; and<a name="line.297"></a>
-<span class="sourceLineNo">298</span>   *   the &lt;code&gt;pair&lt;/code&gt;. Does NOT check the pairs themselves overlap.<a name="line.298"></a>
-<span class="sourceLineNo">299</span>   */<a name="line.299"></a>
-<span class="sourceLineNo">300</span>  @VisibleForTesting<a name="line.300"></a>
-<span class="sourceLineNo">301</span>  static boolean isOverlap(RegionInfo ri, Pair&lt;RegionInfo, RegionInfo&gt; pair) {<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    if (ri == null || pair == null) {<a name="line.302"></a>
-<span class="sourceLineNo">303</span>      // Can't be an overlap in either of these cases.<a name="line.303"></a>
-<span class="sourceLineNo">304</span>      return false;<a name="line.304"></a>
-<span class="sourceLineNo">305</span>    }<a name="line.305"></a>
-<span class="sourceLineNo">306</span>    return ri.isOverlap(pair.getFirst()) || ri.isOverlap(pair.getSecond());<a name="line.306"></a>
-<span class="sourceLineNo">307</span>  }<a name="line.307"></a>
-<span class="sourceLineNo">308</span><a name="line.308"></a>
-<span class="sourceLineNo">309</span>  /**<a name="line.309"></a>
-<span class="sourceLineNo">310</span>   * A union over {@link L} and {@link R}.<a name="line.310"></a>
-<span class="sourceLineNo">311</span>   */<a name="line.311"></a>
-<span class="sourceLineNo">312</span>  private static class Either&lt;L, R&gt; {<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    private final L left;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>    private final R right;<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>    public static &lt;L, R&gt; Either&lt;L, R&gt; ofLeft(L left) {<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      return new Either&lt;&gt;(left, null);<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    }<a name="line.318"></a>
-<span class="sourceLineNo">319</span><a name="line.319"></a>
-<span class="sourceLineNo">320</span>    public static &lt;L, R&gt; Either&lt;L, R&gt; ofRight(R right) {<a name="line.320"></a>
-<span class="sourceLineNo">321</span>      return new Either&lt;&gt;(null, right);<a name="line.321"></a>
-<span class="sourceLineNo">322</span>    }<a name="line.322"></a>
-<span class="sourceLineNo">323</span><a name="line.323"></a>
-<span class="sourceLineNo">324</span>    Either(L left, R right) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>      this.left = left;<a name="line.325"></a>
-<span class="sourceLineNo">326</span>      this.right = right;<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>    public boolean hasLeft() {<a name="line.329"></a>
-<span class="sourceLineNo">330</span>      return left != null;<a name="line.330"></a>
-<span class="sourceLineNo">331</span>    }<a name="line.331"></a>
-<span class="sourceLineNo">332</span><a name="line.332"></a>
-<span class="sourceLineNo">333</span>    public L getLeft() {<a name="line.333"></a>
-<span class="sourceLineNo">334</span>      if (!hasLeft()) {<a name="line.334"></a>
-<span class="sourceLineNo">335</span>        throw new IllegalStateException("Either contains no left.");<a name="line.335"></a>
-<span class="sourceLineNo">336</span>      }<a name="line.336"></a>
-<span class="sourceLineNo">337</span>      return left;<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>    public boolean hasRight() {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>      return right != null;<a name="line.341"></a>
-<span class="sourceLineNo">342</span>    }<a name="line.342"></a>
-<span class="sourceLineNo">343</span><a name="line.343"></a>
-<span class="sourceLineNo">344</span>    public R getRight() {<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      if (!hasRight()) {<a name="line.345"></a>
-<span class="sourceLineNo">346</span>        throw new IllegalStateException("Either contains no right.");<a name="line.346"></a>
-<span class="sourceLineNo">347</span>      }<a name="line.347"></a>
-<span class="sourceLineNo">348</span>      return right;<a name="line.348"></a>
-<span class="sourceLineNo">349</span>    }<a name="line.349"></a>
-<span class="sourceLineNo">350</span>  }<a name="line.350"></a>
-<span class="sourceLineNo">351</span>}<a name="line.351"></a>
+<span class="sourceLineNo">044</span><a name="line.44"></a>
+<span class="sourceLineNo">045</span>/**<a name="line.45"></a>
+<span class="sourceLineNo">046</span> * Server-side fixing of bad or inconsistent state in hbase:meta.<a name="line.46"></a>
+<span class="sourceLineNo">047</span> * Distinct from MetaTableAccessor because {@link MetaTableAccessor} is about low-level<a name="line.47"></a>
+<span class="sourceLineNo">048</span> * manipulations driven by the Master. This class MetaFixer is<a name="line.48"></a>
+<span class="sourceLineNo">049</span> * employed by the Master and it 'knows' about holes and orphans<a name="line.49"></a>
+<span class="sourceLineNo">050</span> * and encapsulates their fixing on behalf of the Master.<a name="line.50"></a>
+<span class="sourceLineNo">051</span> */<a name="line.51"></a>
+<span class="sourceLineNo">052</span>@InterfaceAudience.Private<a name="line.52"></a>
+<span class="sourceLineNo">053</span>class MetaFixer {<a name="line.53"></a>
+<span class="sourceLineNo">054</span>  private static final Logger LOG = LoggerFactory.getLogger(MetaFixer.class);<a name="line.54"></a>
+<span class="sourceLineNo">055</span>  private static final String MAX_MERGE_COUNT_KEY = "hbase.master.metafixer.max.merge.count";<a name="line.55"></a>
+<span class="sourceLineNo">056</span>  private static final int MAX_MERGE_COUNT_DEFAULT = 64;<a name="line.56"></a>
+<span class="sourceLineNo">057</span><a name="line.57"></a>
+<span class="sourceLineNo">058</span>  private final MasterServices masterServices;<a name="line.58"></a>
+<span class="sourceLineNo">059</span>  /**<a name="line.59"></a>
+<span class="sourceLineNo">060</span>   * Maximum for many regions to merge at a time.<a name="line.60"></a>
+<span class="sourceLineNo">061</span>   */<a name="line.61"></a>
+<span class="sourceLineNo">062</span>  private final int maxMergeCount;<a name="line.62"></a>
+<span class="sourceLineNo">063</span><a name="line.63"></a>
+<span class="sourceLineNo">064</span>  MetaFixer(MasterServices masterServices) {<a name="line.64"></a>
+<span class="sourceLineNo">065</span>    this.masterServices = masterServices;<a name="line.65"></a>
+<span class="sourceLineNo">066</span>    this.maxMergeCount = this.masterServices.getConfiguration().<a name="line.66"></a>
+<span class="sourceLineNo">067</span>      getInt(MAX_MERGE_COUNT_KEY, MAX_MERGE_COUNT_DEFAULT);<a name="line.67"></a>
+<span class="sourceLineNo">068</span>  }<a name="line.68"></a>
+<span class="sourceLineNo">069</span><a name="line.69"></a>
+<span class="sourceLineNo">070</span>  void fix() throws IOException {<a name="line.70"></a>
+<span class="sourceLineNo">071</span>    CatalogJanitor.Report report = this.masterServices.getCatalogJanitor().getLastReport();<a name="line.71"></a>
+<span class="sourceLineNo">072</span>    if (report == null) {<a name="line.72"></a>
+<span class="sourceLineNo">073</span>      LOG.info("CatalogJanitor has not generated a report yet; run 'catalogjanitor_run' in " +<a name="line.73"></a>
+<span class="sourceLineNo">074</span>          "shell or wait until CatalogJanitor chore runs.");<a name="line.74"></a>
+<span class="sourceLineNo">075</span>      return;<a name="line.75"></a>
+<span class="sourceLineNo">076</span>    }<a name="line.76"></a>
+<span class="sourceLineNo">077</span>    fixHoles(report);<a name="line.77"></a>
+<span class="sourceLineNo">078</span>    fixOverlaps(report);<a name="line.78"></a>
+<span class="sourceLineNo">079</span>    // Run the ReplicationBarrierCleaner here; it may clear out rep_barrier rows which<a name="line.79"></a>
+<span class="sourceLineNo">080</span>    // can help cleaning up damaged hbase:meta.<a name="line.80"></a>
+<span class="sourceLineNo">081</span>    this.masterServices.runReplicationBarrierCleaner();<a name="line.81"></a>
+<span class="sourceLineNo">082</span>  }<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>   * If hole, it papers it over by adding a region in the filesystem and to hbase:meta.<a name="line.85"></a>
+<span class="sourceLineNo">086</span>   * Does not assign.<a name="line.86"></a>
+<span class="sourceLineNo">087</span>   */<a name="line.87"></a>
+<span class="sourceLineNo">088</span>  void fixHoles(CatalogJanitor.Report report) {<a name="line.88"></a>
+<span class="sourceLineNo">089</span>    final List&lt;Pair&lt;RegionInfo, RegionInfo&gt;&gt; holes = report.getHoles();<a name="line.89"></a>
+<span class="sourceLineNo">090</span>    if (holes.isEmpty()) {<a name="line.90"></a>
+<span class="sourceLineNo">091</span>      LOG.info("CatalogJanitor Report contains no holes to fix. Skipping.");<a name="line.91"></a>
+<span class="sourceLineNo">092</span>      return;<a name="line.92"></a>
+<span class="sourceLineNo">093</span>    }<a name="line.93"></a>
+<span class="sourceLineNo">094</span><a name="line.94"></a>
+<span class="sourceLineNo">095</span>    LOG.info("Identified {} region holes to fix. Detailed fixup progress logged at DEBUG.",<a name="line.95"></a>
+<span class="sourceLineNo">096</span>      holes.size());<a name="line.96"></a>
+<span class="sourceLineNo">097</span><a name="line.97"></a>
+<span class="sourceLineNo">098</span>    final List&lt;RegionInfo&gt; newRegionInfos = createRegionInfosForHoles(holes);<a name="line.98"></a>
+<span class="sourceLineNo">099</span>    final List&lt;RegionInfo&gt; newMetaEntries = createMetaEntries(masterServices, newRegionInfos);<a name="line.99"></a>
+<span class="sourceLineNo">100</span>    final TransitRegionStateProcedure[] assignProcedures = masterServices<a name="line.100"></a>
+<span class="sourceLineNo">101</span>      .getAssignmentManager()<a name="line.101"></a>
+<span class="sourceLineNo">102</span>      .createRoundRobinAssignProcedures(newMetaEntries);<a name="line.102"></a>
+<span class="sourceLineNo">103</span><a name="line.103"></a>
+<span class="sourceLineNo">104</span>    masterServices.getMasterProcedureExecutor().submitProcedures(assignProcedures);<a name="line.104"></a>
+<span class="sourceLineNo">105</span>    LOG.info(<a name="line.105"></a>
+<span class="sourceLineNo">106</span>      "Scheduled {}/{} new regions for assignment.", assignProcedures.length, holes.size());<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>
+<span class="sourceLineNo">110</span>   * Create a new {@link RegionInfo} corresponding to each provided "hole" pair.<a name="line.110"></a>
+<span class="sourceLineNo">111</span>   */<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  private static List&lt;RegionInfo&gt; createRegionInfosForHoles(<a name="line.112"></a>
+<span class="sourceLineNo">113</span>    final List&lt;Pair&lt;RegionInfo, RegionInfo&gt;&gt; holes) {<a name="line.113"></a>
+<span class="sourceLineNo">114</span>    final List&lt;RegionInfo&gt; newRegionInfos = holes.stream()<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      .map(MetaFixer::getHoleCover)<a name="line.115"></a>
+<span class="sourceLineNo">116</span>      .filter(Optional::isPresent)<a name="line.116"></a>
+<span class="sourceLineNo">117</span>      .map(Optional::get)<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      .collect(Collectors.toList());<a name="line.118"></a>
+<span class="sourceLineNo">119</span>    LOG.debug("Constructed {}/{} RegionInfo descriptors corresponding to identified holes.",<a name="line.119"></a>
+<span class="sourceLineNo">120</span>      newRegionInfos.size(), holes.size());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>    return newRegionInfos;<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>  /**<a name="line.124"></a>
+<span class="sourceLineNo">125</span>   * @return Attempts to calculate a new {@link RegionInfo} that covers the region range described<a name="line.125"></a>
+<span class="sourceLineNo">126</span>   *   in {@code hole}.<a name="line.126"></a>
+<span class="sourceLineNo">127</span>   */<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private static Optional&lt;RegionInfo&gt; getHoleCover(Pair&lt;RegionInfo, RegionInfo&gt; hole) {<a name="line.128"></a>
+<span class="sourceLineNo">129</span>    final RegionInfo left = hole.getFirst();<a name="line.129"></a>
+<span class="sourceLineNo">130</span>    final RegionInfo right = hole.getSecond();<a name="line.130"></a>
+<span class="sourceLineNo">131</span><a name="line.131"></a>
+<span class="sourceLineNo">132</span>    if (left.getTable().equals(right.getTable())) {<a name="line.132"></a>
+<span class="sourceLineNo">133</span>      // Simple case.<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      if (Bytes.compareTo(left.getEndKey(), right.getStartKey()) &gt;= 0) {<a name="line.134"></a>
+<span class="sourceLineNo">135</span>        LOG.warn("Skipping hole fix; left-side endKey is not less than right-side startKey;"<a name="line.135"></a>
+<span class="sourceLineNo">136</span>          + " left=&lt;{}&gt;, right=&lt;{}&gt;", left, right);<a name="line.136"></a>
+<span class="sourceLineNo">137</span>        return Optional.empty();<a name="line.137"></a>
+<span class="sourceLineNo">138</span>      }<a name="line.138"></a>
+<span class="sourceLineNo">139</span>      return Optional.of(buildRegionInfo(left.getTable(), left.getEndKey(), right.getStartKey()));<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>    final boolean leftUndefined = left.equals(RegionInfo.UNDEFINED);<a name="line.142"></a>
+<span class="sourceLineNo">143</span>    final boolean rightUndefined = right.equals(RegionInfo.UNDEFINED);<a name="line.143"></a>
+<span class="sourceLineNo">144</span>    final boolean last = left.isLast();<a name="line.144"></a>
+<span class="sourceLineNo">145</span>    final boolean first = right.isFirst();<a name="line.145"></a>
+<span class="sourceLineNo">146</span>    if (leftUndefined &amp;&amp; rightUndefined) {<a name="line.146"></a>
+<span class="sourceLineNo">147</span>      LOG.warn("Skipping hole fix; both the hole left-side and right-side RegionInfos are " +<a name="line.147"></a>
+<span class="sourceLineNo">148</span>        "UNDEFINED; left=&lt;{}&gt;, right=&lt;{}&gt;", left, right);<a name="line.148"></a>
+<span class="sourceLineNo">149</span>      return Optional.empty();<a name="line.149"></a>
+<span class="sourceLineNo">150</span>    }<a name="line.150"></a>
+<span class="sourceLineNo">151</span>    if (leftUndefined || last) {<a name="line.151"></a>
+<span class="sourceLineNo">152</span>      return Optional.of(<a name="line.152"></a>
+<span class="sourceLineNo">153</span>        buildRegionInfo(right.getTable(), HConstants.EMPTY_START_ROW, right.getStartKey()));<a name="line.153"></a>
+<span class="sourceLineNo">154</span>    }<a name="line.154"></a>
+<span class="sourceLineNo">155</span>    if (rightUndefined || first) {<a name="line.155"></a>
+<span class="sourceLineNo">156</span>      return Optional.of(<a name="line.156"></a>
+<span class="sourceLineNo">157</span>        buildRegionInfo(left.getTable(), left.getEndKey(), HConstants.EMPTY_END_ROW));<a name="line.157"></a>
+<span class="sourceLineNo">158</span>    }<a name="line.158"></a>
+<span class="sourceLineNo">159</span>    LOG.warn("Skipping hole fix; don't know what to do with left=&lt;{}&gt;, right=&lt;{}&gt;", left, right);<a name="line.159"></a>
+<span class="sourceLineNo">160</span>    return Optional.empty();<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  }<a name="line.161"></a>
+<span class="sourceLineNo">162</span><a name="line.162"></a>
+<span class="sourceLineNo">163</span>  private static RegionInfo buildRegionInfo(TableName tn, byte [] start, byte [] end) {<a name="line.163"></a>
+<span class="sourceLineNo">164</span>    return RegionInfoBuilder.newBuilder(tn).setStartKey(start).setEndKey(end).build();<a name="line.164"></a>
+<span class="sourceLineNo">165</span>  }<a name="line.165"></a>
+<span class="sourceLineNo">166</span><a name="line.166"></a>
+<span class="sourceLineNo">167</span>  /**<a name="line.167"></a>
+<span class="sourceLineNo">168</span>   * Create entries in the {@code hbase:meta} for each provided {@link RegionInfo}. Best effort.<a name="line.168"></a>
+<span class="sourceLineNo">169</span>   * @param masterServices used to connect to {@code hbase:meta}<a name="line.169"></a>
+<span class="sourceLineNo">170</span>   * @param newRegionInfos the new {@link RegionInfo} entries to add to the filesystem<a name="line.170"></a>
+<span class="sourceLineNo">171</span>   * @return a list of {@link RegionInfo} entries for which {@code hbase:meta} entries were<a name="line.171"></a>
+<span class="sourceLineNo">172</span>   *   successfully created<a name="line.172"></a>
+<span class="sourceLineNo">173</span>   */<a name="line.173"></a>
+<span class="sourceLineNo">174</span>  private static List&lt;RegionInfo&gt; createMetaEntries(final MasterServices masterServices,<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    final List&lt;RegionInfo&gt; newRegionInfos) {<a name="line.175"></a>
+<span class="sourceLineNo">176</span><a name="line.176"></a>
+<span class="sourceLineNo">177</span>    final List&lt;Either&lt;RegionInfo, IOException&gt;&gt; addMetaEntriesResults = newRegionInfos.stream()<a name="line.177"></a>
+<span class="sourceLineNo">178</span>      .map(regionInfo -&gt; {<a name="line.178"></a>
+<span class="sourceLineNo">179</span>        try {<a name="line.179"></a>
+<span class="sourceLineNo">180</span>          MetaTableAccessor.addRegionToMeta(masterServices.getConnection(), regionInfo);<a name="line.180"></a>
+<span class="sourceLineNo">181</span>          masterServices.getAssignmentManager()<a name="line.181"></a>
+<span class="sourceLineNo">182</span>            .getRegionStates()<a name="line.182"></a>
+<span class="sourceLineNo">183</span>            .updateRegionState(regionInfo, RegionState.State.CLOSED);<a name="line.183"></a>
+<span class="sourceLineNo">184</span>          return Either.&lt;RegionInfo, IOException&gt;ofLeft(regionInfo);<a name="line.184"></a>
+<span class="sourceLineNo">185</span>        } catch (IOException e) {<a name="line.185"></a>
+<span class="sourceLineNo">186</span>          return Either.&lt;RegionInfo, IOException&gt;ofRight(e);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>        }<a name="line.187"></a>
+<span class="sourceLineNo">188</span>      })<a name="line.188"></a>
+<span class="sourceLineNo">189</span>      .collect(Collectors.toList());<a name="line.189"></a>
+<span class="sourceLineNo">190</span>    final List&lt;RegionInfo&gt; createMetaEntriesSuccesses = addMetaEntriesResults.stream()<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      .filter(Either::hasLeft)<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      .map(Either::getLeft)<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      .collect(Collectors.toList());<a name="line.193"></a>
+<span class="sourceLineNo">194</span>    final List&lt;IOException&gt; createMetaEntriesFailures = addMetaEntriesResults.stream()<a name="line.194"></a>
+<span class="sourceLineNo">195</span>      .filter(Either::hasRight)<a name="line.195"></a>
+<span class="sourceLineNo">196</span>      .map(Either::getRight)<a name="line.196"></a>
+<span class="sourceLineNo">197</span>      .collect(Collectors.toList());<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    LOG.debug("Added {}/{} entries to hbase:meta",<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      createMetaEntriesSuccesses.size(), newRegionInfos.size());<a name="line.199"></a>
+<span class="sourceLineNo">200</span><a name="line.200"></a>
+<span class="sourceLineNo">201</span>    if (!createMetaEntriesFailures.isEmpty()) {<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      LOG.warn("Failed to create entries in hbase:meta for {}/{} RegionInfo descriptors. First"<a name="line.202"></a>
+<span class="sourceLineNo">203</span>          + " failure message included; full list of failures with accompanying stack traces is"<a name="line.203"></a>
+<span class="sourceLineNo">204</span>          + " available at log level DEBUG. message={}", createMetaEntriesFailures.size(),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>        addMetaEntriesResults.size(), createMetaEntriesFailures.get(0).getMessage());<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      if (LOG.isDebugEnabled()) {<a name="line.206"></a>
+<span class="sourceLineNo">207</span>        createMetaEntriesFailures.forEach(<a name="line.207"></a>
+<span class="sourceLineNo">208</span>          ioe -&gt; LOG.debug("Attempt to fix region hole in hbase:meta failed.", ioe));<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      }<a name="line.209"></a>
+<span class="sourceLineNo">210</span>    }<a name="line.210"></a>
+<span class="sourceLineNo">211</span><a name="line.211"></a>
+<span class="sourceLineNo">212</span>    return createMetaEntriesSuccesses;<a name="line.212"></a>
+<span class="sourceLineNo">213</span>  }<a name="line.213"></a>
+<span class="sourceLineNo">214</span><a name="line.214"></a>
+<span class="sourceLineNo">215</span>  /**<a name="line.215"></a>
+<span class="sourceLineNo">216</span>   * Fix overlaps noted in CJ consistency report.<a name="line.216"></a>
+<span class="sourceLineNo">217</span>   */<a name="line.217"></a>
+<span class="sourceLineNo">218</span>  void fixOverlaps(CatalogJanitor.Report report) throws IOException {<a name="line.218"></a>
+<span class="sourceLineNo">219</span>    for (Set&lt;RegionInfo&gt; regions: calculateMerges(maxMergeCount, report.getOverlaps())) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>      RegionInfo [] regionsArray = regions.toArray(new RegionInfo [] {});<a name="line.220"></a>
+<span class="sourceLineNo">221</span>      try {<a name="line.221"></a>
+<span class="sourceLineNo">222</span>        this.masterServices.mergeRegions(regionsArray,<a name="line.222"></a>
+<span class="sourceLineNo">223</span>            true, HConstants.NO_NONCE, HConstants.NO_NONCE);<a name="line.223"></a>
+<span class="sourceLineNo">224</span>      } catch (MergeRegionException mre) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>        LOG.warn("Failed overlap fix of {}", regionsArray, mre);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>      }<a name="line.226"></a>
+<span class="sourceLineNo">227</span>    }<a name="line.227"></a>
+<span class="sourceLineNo">228</span>  }<a name="line.228"></a>
+<span class="sourceLineNo">229</span><a name="line.229"></a>
+<span class="sourceLineNo">230</span>  /**<a name="line.230"></a>
+<span class="sourceLineNo">231</span>   * Run through &lt;code&gt;overlaps&lt;/code&gt; and return a list of merges to run.<a name="line.231"></a>
+<span class="sourceLineNo">232</span>   * Presumes overlaps are ordered (which they are coming out of the CatalogJanitor<a name="line.232"></a>
+<span class="sourceLineNo">233</span>   * consistency report).<a name="line.233"></a>
+<span class="sourceLineNo">234</span>   * @param maxMergeCount Maximum regions to merge at a time (avoid merging<a name="line.234"></a>
+<span class="sourceLineNo">235</span>   *   100k regions in one go!)<a name="line.235"></a>
+<span class="sourceLineNo">236</span>   */<a name="line.236"></a>
+<span class="sourceLineNo">237</span>  @VisibleForTesting<a name="line.237"></a>
+<span class="sourceLineNo">238</span>  static List&lt;SortedSet&lt;RegionInfo&gt;&gt; calculateMerges(int maxMergeCount,<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      List&lt;Pair&lt;RegionInfo, RegionInfo&gt;&gt; overlaps) {<a name="line.239"></a>
+<span class="sourceLineNo">240</span>    if (overlaps.isEmpty()) {<a name="line.240"></a>
+<span class="sourceLineNo">241</span>      LOG.debug("No overlaps.");<a name="line.241"></a>
+<span class="sourceLineNo">242</span>      return Collections.emptyList();<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    }<a name="line.243"></a>
+<span class="sourceLineNo">244</span>    List&lt;SortedSet&lt;RegionInfo&gt;&gt; merges = new ArrayList&lt;&gt;();<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    SortedSet&lt;RegionInfo&gt; currentMergeSet = new TreeSet&lt;&gt;();<a name="line.245"></a>
+<span class="sourceLineNo">246</span>    HashSet&lt;RegionInfo&gt; regionsInMergeSet = new HashSet&lt;&gt;();<a name="line.246"></a>
+<span class="sourceLineNo">247</span>    RegionInfo regionInfoWithlargestEndKey =  null;<a name="line.247"></a>
+<span class="sourceLineNo">248</span>    for (Pair&lt;RegionInfo, RegionInfo&gt; pair: overlaps) {<a name="line.248"></a>
+<span class="sourceLineNo">249</span>      if (regionInfoWithlargestEndKey != null) {<a name="line.249"></a>
+<span class="sourceLineNo">250</span>        if (!isOverlap(regionInfoWithlargestEndKey, pair) ||<a name="line.250"></a>
+<span class="sourceLineNo">251</span>            currentMergeSet.size() &gt;= maxMergeCount) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>          // Log when we cut-off-merge because we hit the configured maximum merge limit.<a name="line.252"></a>
+<span class="sourceLineNo">253</span>          if (currentMergeSet.size() &gt;= maxMergeCount) {<a name="line.253"></a>
+<span class="sourceLineNo">254</span>            LOG.warn("Ran into maximum-at-a-time merges limit={}", maxMergeCount);<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>          // In the case of the merge set contains only 1 region or empty, it does not need to<a name="line.257"></a>
+<span class="sourceLineNo">258</span>          // submit this merge request as no merge is going to happen. currentMergeSet can be<a name="line.258"></a>
+<span class="sourceLineNo">259</span>          // reused in this case.<a name="line.259"></a>
+<span class="sourceLineNo">260</span>          if (currentMergeSet.size() &lt;= 1) {<a name="line.260"></a>
+<span class="sourceLineNo">261</span>            for (RegionInfo ri : currentMergeSet) {<a name="line.261"></a>
+<span class="sourceLineNo">262</span>              regionsInMergeSet.remove(ri);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>            }<a name="line.263"></a>
+<span class="sourceLineNo">264</span>            currentMergeSet.clear();<a name="line.264"></a>
+<span class="sourceLineNo">265</span>          } else {<a name="line.265"></a>
+<span class="sourceLineNo">266</span>            merges.add(currentMergeSet);<a name="line.266"></a>
+<span class="sourceLineNo">267</span>            currentMergeSet = new TreeSet&lt;&gt;();<a name="line.267"></a>
+<span class="sourceLineNo">268</span>          }<a name="line.268"></a>
+<span class="sourceLineNo">269</span>        }<a name="line.269"></a>
+<span class="sourceLineNo">270</span>      }<a name="line.270"></a>
+<span class="sourceLineNo">271</span><a name="line.271"></a>
+<span class="sourceLineNo">272</span>      // Do not add the same region into multiple merge set, this will fail<a name="line.272"></a>
+<span class="sourceLineNo">273</span>      // the second merge request.<a name="line.273"></a>
+<span class="sourceLineNo">274</span>      if (!regionsInMergeSet.contains(pair.getFirst())) {<a name="line.274"></a>
+<span class="sourceLineNo">275</span>        currentMergeSet.add(pair.getFirst());<a name="line.275"></a>
+<span class="sourceLineNo">276</span>        regionsInMergeSet.add(pair.getFirst());<a name="line.276"></a>
+<span class="sourceLineNo">277</span>      }<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (!regionsInMergeSet.contains(pair.getSecond())) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        currentMergeSet.add(pair.getSecond());<a name="line.279"></a>
+<span class="sourceLineNo">280</span>        regionsInMergeSet.add(pair.getSecond());<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>      regionInfoWithlargestEndKey = getRegionInfoWithLargestEndKey(<a name="line.283"></a>
+<span class="sourceLineNo">284</span>        getRegionInfoWithLargestEndKey(pair.getFirst(), pair.getSecond()),<a name="line.284"></a>
+<span class="sourceLineNo">285</span>          regionInfoWithlargestEndKey);<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span>    merges.add(currentMergeSet);<a name="line.287"></a>
+<span class="sourceLineNo">288</span>    return merges;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>  }<a name="line.289"></a>
+<span class="sourceLineNo">290</span><a name="line.290"></a>
+<span class="sourceLineNo">291</span>  /**<a name="line.291"></a>
+<span class="sourceLineNo">292</span>   * @return Either &lt;code&gt;a&lt;/code&gt; or &lt;code&gt;b&lt;/code&gt;, whichever has the<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   *   endkey that is furthest along in the Table.<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
+<span class="sourceLineNo">295</span>  @VisibleForTesting<a name="line.295"></a>
+<span class="sourceLineNo">296</span>  static RegionInfo getRegionInfoWithLargestEndKey(RegionInfo a, RegionInfo b) {<a name="line.296"></a>
+<span class="sourceLineNo">297</span>    if (a == null) {<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      // b may be null.<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      return b;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>    }<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    if (b == null) {<a name="line.301"></a>
+<span class="sourceLineNo">302</span>      // Both are null. The return is not-defined.<a name="line.302"></a>
+<span class="sourceLineNo">303</span>      return a;<a name="line.303"></a>
+<span class="sourceLineNo">304</span>    }<a name="line.304"></a>
+<span class="sourceLineNo">305</span>    if (!a.getTable().equals(b.getTable())) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>      // This is an odd one. This should be the right answer.<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      return b;<a name="line.307"></a>
+<span class="sourceLineNo">308</span>    }<a name="line.308"></a>
+<span class="sourceLineNo">309</span>    if (a.isLast()) {<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return a;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    if (b.isLast()) {<a name="line.312"></a>
+<span class="sourceLineNo">313</span>      return b;<a name="line.313"></a>
+<span class="sourceLineNo">314</span>    }<a name="line.314"></a>
+<span class="sourceLineNo">315</span>    int compare = Bytes.compareTo(a.getEndKey(), b.getEndKey());<a name="line.315"></a>
+<span class="sourceLineNo">316</span>    return compare == 0 || compare &gt; 0? a: b;<a name="line.316"></a>
+<span class="sourceLineNo">317</span>  }<a name="line.317"></a>
+<span class="sourceLineNo">318</span><a name="line.318"></a>
+<span class="sourceLineNo">319</span>  /**<a name="line.319"></a>
+<span class="sourceLineNo">320</span>   * @return True if an overlap found between passed in &lt;code&gt;ri&lt;/code&gt; and<a name="line.320"></a>
+<span class="sourceLineNo">321</span>   *   the &lt;code&gt;pair&lt;/code&gt;. Does NOT check the pairs themselves overlap.<a name="line.321"></a>
+<span class="sourceLineNo">322</span>   */<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
+<span class="sourceLineNo">324</span>  static boolean isOverlap(RegionInfo ri, Pair&lt;RegionInfo, RegionInfo&gt; pair) {<a name="line.324"></a>
+<span class="sourceLineNo">325</span>    if (ri == null || pair == null) {<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      // Can't be an overlap in either of these cases.<a name="line.326"></a>
+<span class="sourceLineNo">327</span>      return false;<a name="line.327"></a>
+<span class="sourceLineNo">328</span>    }<a name="line.328"></a>
+<span class="sourceLineNo">329</span>    return ri.isOverlap(pair.getFirst()) || ri.isOverlap(pair.getSecond());<a name="line.329"></a>
+<span class="sourceLineNo">330</span>  }<a name="line.330"></a>
+<span class="sourceLineNo">331</span><a name="line.331"></a>
+<span class="sourceLineNo">332</span>  /**<a name="line.332"></a>
+<span class="sourceLineNo">333</span>   * A union over {@link L} and {@link R}.<a name="line.333"></a>
+<span class="sourceLineNo">334</span>   */<a name="line.334"></a>
+<span class="sourceLineNo">335</span>  private static class Either&lt;L, R&gt; {<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    private final L left;<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    private final R right;<a name="line.337"></a>
+<span class="sourceLineNo">338</span><a name="line.338"></a>
+<span class="sourceLineNo">339</span>    public static &lt;L, R&gt; Either&lt;L, R&gt; ofLeft(L left) {<a name="line.339"></a>
+<span class="sourceLineNo">340</span>      return new Either&lt;&gt;(left, null);<a name="line.340"></a>
+<span class="sourceLineNo">341</span>    }<a name="line.341"></a>
+<span class="sourceLineNo">342</span><a name="line.342"></a>
+<span class="sourceLineNo">343</span>    public static &lt;L, R&gt; Either&lt;L, R&gt; ofRight(R right) {<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      return new Either&lt;&gt;(null, right);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    }<a name="line.345"></a>
+<span class="sourceLineNo">346</span><a name="line.346"></a>
+<span class="sourceLineNo">347</span>    Either(L left, R right) {<a name="line.347"></a>
+<span class="sourceLineNo">348</span>      this.left = left;<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      this.right = right;<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    }<a name="line.350"></a>
+<span class="sourceLineNo">351</span><a name="line.351"></a>
+<span class="sourceLineNo">352</span>    public boolean hasLeft() {<a name="line.352"></a>
+<span class="sourceLineNo">353</span>      return left != null;<a name="line.353"></a>
+<span class="sourceLineNo">354</span>    }<a name="line.354"></a>
+<span class="sourceLineNo">355</span><a name="line.355"></a>
+<span class="sourceLineNo">356</span>    public L getLeft() {<a name="line.356"></a>
+<span class="sourceLineNo">357</span>      if (!hasLeft()) {<a name="line.357"></a>
+<span class="sourceLineNo">358</span>        throw new IllegalStateException("Either contains no left.");<a name="line.358"></a>
+<span class="sourceLineNo">359</span>      }<a name="line.359"></a>
+<span class="sourceLineNo">360</span>      return left;<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>    public boolean hasRight() {<a name="line.363"></a>
+<span class="sourceLineNo">364</span>      return right != null;<a name="line.364"></a>
+<span class="sourceLineNo">365</span>    }<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    public R getRight() {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      if (!hasRight()) {<a name="line.368"></a>
+<span class="sourceLineNo">369</span>        throw new IllegalStateException("Either contains no right.");<a name="line.369"></a>
+<span class="sourceLineNo">370</span>      }<a name="line.370"></a>
+<span class="sourceLineNo">371</span>      return right;<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>}<a name="line.374"></a>
 
 
 
diff --git a/downloads.html b/downloads.html
index 0b9d93e..bc1844f 100644
--- a/downloads.html
+++ b/downloads.html
@@ -434,7 +434,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/export_control.html b/export_control.html
index cd94955..200b73e 100644
--- a/export_control.html
+++ b/export_control.html
@@ -197,7 +197,7 @@ for more details.</p>
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/index.html b/index.html
index c5b9113..edf3053 100644
--- a/index.html
+++ b/index.html
@@ -275,7 +275,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/issue-tracking.html b/issue-tracking.html
index 16b397f..3afc0ea 100644
--- a/issue-tracking.html
+++ b/issue-tracking.html
@@ -169,7 +169,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/mail-lists.html b/mail-lists.html
index 1ade595..61841b6 100644
--- a/mail-lists.html
+++ b/mail-lists.html
@@ -229,7 +229,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/metrics.html b/metrics.html
index 99da26c..38b9376 100644
--- a/metrics.html
+++ b/metrics.html
@@ -325,7 +325,7 @@ export HBASE_REGIONSERVER_OPTS=&quot;$HBASE_JMX_OPTS -Dcom.sun.management.jmxrem
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/old_news.html b/old_news.html
index bce680c..2ed3cfc 100644
--- a/old_news.html
+++ b/old_news.html
@@ -316,7 +316,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/plugin-management.html b/plugin-management.html
index 3173550..1640ab2 100644
--- a/plugin-management.html
+++ b/plugin-management.html
@@ -321,7 +321,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/plugins.html b/plugins.html
index 011e17c..a58aa60 100644
--- a/plugins.html
+++ b/plugins.html
@@ -248,7 +248,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/poweredbyhbase.html b/poweredbyhbase.html
index e29dcae..5303c3e 100644
--- a/poweredbyhbase.html
+++ b/poweredbyhbase.html
@@ -650,7 +650,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/project-info.html b/project-info.html
index 709ef5b..f67f40d 100644
--- a/project-info.html
+++ b/project-info.html
@@ -210,7 +210,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/project-reports.html b/project-reports.html
index 579396a..85de7f6 100644
--- a/project-reports.html
+++ b/project-reports.html
@@ -186,7 +186,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/project-summary.html b/project-summary.html
index 3ebc25b..58e14a8 100644
--- a/project-summary.html
+++ b/project-summary.html
@@ -212,7 +212,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/pseudo-distributed.html b/pseudo-distributed.html
index b01f33d..f99b6d7 100644
--- a/pseudo-distributed.html
+++ b/pseudo-distributed.html
@@ -174,7 +174,7 @@ Running Apache HBase (TM) in pseudo-distributed mode
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/replication.html b/replication.html
index 110a5c8..44c85f1 100644
--- a/replication.html
+++ b/replication.html
@@ -169,7 +169,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/resources.html b/resources.html
index 6d38fca..5a11efb 100644
--- a/resources.html
+++ b/resources.html
@@ -197,7 +197,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/source-repository.html b/source-repository.html
index f33d3ce..5049e4d 100644
--- a/source-repository.html
+++ b/source-repository.html
@@ -180,7 +180,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/sponsors.html b/sponsors.html
index 66d3cdc..c8d3864 100644
--- a/sponsors.html
+++ b/sponsors.html
@@ -199,7 +199,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/supportingprojects.html b/supportingprojects.html
index e4bf9b2..6937bb4 100644
--- a/supportingprojects.html
+++ b/supportingprojects.html
@@ -390,7 +390,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/team-list.html b/team-list.html
index ff5a724..ee7a895 100644
--- a/team-list.html
+++ b/team-list.html
@@ -701,7 +701,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2020
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-08</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-05-09</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/testdevapidocs/index-all.html b/testdevapidocs/index-all.html
index 75a7c0d..c689248 100644
--- a/testdevapidocs/index-all.html
+++ b/testdevapidocs/index-all.html
@@ -65180,12 +65180,16 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/TestMetaFixer.html#testOverlap--">testOverlap()</a></span> - Method in class org.apache.hadoop.hbase.master.<a href="org/apache/hadoop/hbase/master/TestMetaFixer.html" title="class in org.apache.hadoop.hbase.master">TestMetaFixer</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/TestMetaFixer.html#testOverlapCommon-org.apache.hadoop.hbase.TableName-">testOverlapCommon(TableName)</a></span> - Method in class org.apache.hadoop.hbase.master.<a href="org/apache/hadoop/hbase/master/TestMetaFixer.html" title="class in org.apache.hadoop.hbase.master">TestMetaFixer</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/TestCellUtil.html#testOverlappingKeys--">testOverlappingKeys()</a></span> - Method in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/TestCellUtil.html" title="class in org.apache.hadoop.hbase">TestCellUtil</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/TestMetaFixer.html#testOverlapWithMergeOfNonContiguous--">testOverlapWithMergeOfNonContiguous()</a></span> - Method in class org.apache.hadoop.hbase.master.<a href="org/apache/hadoop/hbase/master/TestMetaFixer.html" title="class in org.apache.hadoop.hbase.master">TestMetaFixer</a></dt>
 <dd>
 <div class="block">Make it so a big overlap spans many Regions, some of which are non-contiguous.</div>
 </dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/TestMetaFixer.html#testOverlapWithSmallMergeCount--">testOverlapWithSmallMergeCount()</a></span> - Method in class org.apache.hadoop.hbase.master.<a href="org/apache/hadoop/hbase/master/TestMetaFixer.html" title="class in org.apache.hadoop.hbase.master">TestMetaFixer</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancerHeterogeneousCost.html#testOverloaded--">testOverloaded()</a></span> - Method in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancerHeterogeneousCost.html" title="class in org.apache.hadoop.hbase.master.balancer">TestStochasticLoadBalancerHeterogeneousCost</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/TestHBaseTestingUtility.html#testOverridingOfDefaultPorts--">testOverridingOfDefaultPorts()</a></span> - Method in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/TestHBaseTestingUtility.html" title="class in org.apache.hadoop.hbase">TestHBaseTestingUtility</a></dt>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/master/TestMetaFixer.html b/testdevapidocs/org/apache/hadoop/hbase/master/TestMetaFixer.html
index 4112d5d..4552c99 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/master/TestMetaFixer.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/master/TestMetaFixer.html
@@ -18,7 +18,7 @@
     catch(err) {
     }
 //-->
-var methods = {"i0":9,"i1":10,"i2":9,"i3":9,"i4":9,"i5":10,"i6":10,"i7":10,"i8":10};
+var methods = {"i0":9,"i1":10,"i2":9,"i3":9,"i4":9,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":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";
@@ -109,7 +109,7 @@ var activeTableTab = "activeTableTab";
 <li class="blockList">
 <hr>
 <br>
-<pre>public class <a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.53">TestMetaFixer</a>
+<pre>public class <a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.57">TestMetaFixer</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>
@@ -212,12 +212,20 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/TestMetaFixer.html#testOverlap--">testOverlap</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i7" class="rowColor">
+<td class="colFirst"><code>private void</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/TestMetaFixer.html#testOverlapCommon-org.apache.hadoop.hbase.TableName-">testOverlapCommon</a></span>(org.apache.hadoop.hbase.TableName&nbsp;tn)</code>&nbsp;</td>
+</tr>
+<tr id="i8" class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/TestMetaFixer.html#testOverlapWithMergeOfNonContiguous--">testOverlapWithMergeOfNonContiguous</a></span>()</code>
 <div class="block">Make it so a big overlap spans many Regions, some of which are non-contiguous.</div>
 </td>
 </tr>
-<tr id="i8" class="altColor">
+<tr id="i9" class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/TestMetaFixer.html#testOverlapWithSmallMergeCount--">testOverlapWithSmallMergeCount</a></span>()</code>&nbsp;</td>
+</tr>
+<tr id="i10" class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/TestMetaFixer.html#testPlugsHoles--">testPlugsHoles</a></span>()</code>&nbsp;</td>
 </tr>
@@ -249,7 +257,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <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/TestMetaFixer.html#line.55">CLASS_RULE</a></pre>
+<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/TestMetaFixer.html#line.59">CLASS_RULE</a></pre>
 </li>
 </ul>
 <a name="name">
@@ -258,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>name</h4>
-<pre>public&nbsp;org.junit.rules.TestName <a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.58">name</a></pre>
+<pre>public&nbsp;org.junit.rules.TestName <a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.62">name</a></pre>
 </li>
 </ul>
 <a name="TEST_UTIL">
@@ -267,7 +275,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>TEST_UTIL</h4>
-<pre>private 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/TestMetaFixer.html#line.60">TEST_UTIL</a></pre>
+<pre>private 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/TestMetaFixer.html#line.64">TEST_UTIL</a></pre>
 </li>
 </ul>
 </li>
@@ -284,7 +292,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>TestMetaFixer</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.53">TestMetaFixer</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.57">TestMetaFixer</a>()</pre>
 </li>
 </ul>
 </li>
@@ -301,7 +309,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>setupBeforeClass</h4>
-<pre>public static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.63">setupBeforeClass</a>()
+<pre>public static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.67">setupBeforeClass</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>
@@ -315,7 +323,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>tearDownAfterClass</h4>
-<pre>public static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.68">tearDownAfterClass</a>()
+<pre>public static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.72">tearDownAfterClass</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>
@@ -329,7 +337,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>deleteRegion</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.72">deleteRegion</a>(org.apache.hadoop.hbase.master.MasterServices&nbsp;services,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.76">deleteRegion</a>(org.apache.hadoop.hbase.master.MasterServices&nbsp;services,
                           org.apache.hadoop.hbase.client.RegionInfo&nbsp;ri)
                    throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
@@ -344,7 +352,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testPlugsHoles</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.79">testPlugsHoles</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.83">testPlugsHoles</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>
@@ -358,7 +366,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testOneRegionTable</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.121">testOneRegionTable</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.125">testOneRegionTable</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">Just make sure running fixMeta does right thing for the case
  of a single-region Table where the region gets dropped.
@@ -376,7 +384,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>makeOverlap</h4>
-<pre>private static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.140">makeOverlap</a>(org.apache.hadoop.hbase.master.MasterServices&nbsp;services,
+<pre>private static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.144">makeOverlap</a>(org.apache.hadoop.hbase.master.MasterServices&nbsp;services,
                                 org.apache.hadoop.hbase.client.RegionInfo&nbsp;a,
                                 org.apache.hadoop.hbase.client.RegionInfo&nbsp;b)
                          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>
@@ -386,13 +394,27 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 </dl>
 </li>
 </ul>
+<a name="testOverlapCommon-org.apache.hadoop.hbase.TableName-">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>testOverlapCommon</h4>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.157">testOverlapCommon</a>(org.apache.hadoop.hbase.TableName&nbsp;tn)
+                        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="testOverlap--">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
 <h4>testOverlap</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.154">testOverlap</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.174">testOverlap</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>
@@ -400,13 +422,27 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 </dl>
 </li>
 </ul>
+<a name="testOverlapWithSmallMergeCount--">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>testOverlapWithSmallMergeCount</h4>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.228">testOverlapWithSmallMergeCount</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="testOverlapWithMergeOfNonContiguous--">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
 <h4>testOverlapWithMergeOfNonContiguous</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.221">testOverlapWithMergeOfNonContiguous</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.316">testOverlapWithMergeOfNonContiguous</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>
 <div class="block">Make it so a big overlap spans many Regions, some of which are non-contiguous. Make it so
  we can fix this condition. HBASE-24247</div>
@@ -422,7 +458,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>await</h4>
-<pre>private static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.265">await</a>(long&nbsp;sleepMillis,
+<pre>private static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html#line.360">await</a>(long&nbsp;sleepMillis,
                           <a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/BooleanSupplier.html?is-external=true" title="class or interface in java.util.function">BooleanSupplier</a>&nbsp;condition)
                    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>
 <div class="block">Await the successful return of <code>condition</code>, sleeping <code>sleepMillis</code> between
diff --git a/testdevapidocs/org/apache/hadoop/hbase/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
index d31076f..09ec5f3 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
@@ -670,16 +670,16 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/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/ScanPerformanceEvaluation.ScanCounter.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ScanPerformanceEvaluation.ScanCounter</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClusterManager.ServiceType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClusterManager.ServiceType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestDDLMasterFailover.ACTION.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestDDLMasterFailover.ACTION</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/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/HBaseClusterManager.Signal.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HBaseClusterManager.Signal</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.RoleCommand.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.RoleCommand</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestRegionReplicaPerf.Stat.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestRegionReplicaPerf.Stat</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/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/PerformanceEvaluation.Counter.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">PerformanceEvaluation.Counter</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.Service.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.Service</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HBaseClusterManager.Signal.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HBaseClusterManager.Signal</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/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/ClusterManager.ServiceType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClusterManager.ServiceType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestDDLMasterFailover.ACTION.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestDDLMasterFailover.ACTION</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/procedure/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/procedure/package-tree.html
index c6bce5f..8ff917c 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/procedure/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/procedure/package-tree.html
@@ -81,14 +81,14 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Object</span></a>
 <ul>
-<li type="circle">org.apache.hadoop.hbase.procedure2.Procedure&lt;TEnvironment&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;)
+<li type="circle">org.apache.hadoop.hbase.procedure.Procedure (implements java.util.concurrent.<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html?is-external=true" title="class or interface in java.util.concurrent">Callable</a>&lt;V&gt;, org.apache.hadoop.hbase.errorhandling.ForeignExceptionListener)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.procedure.<a href="../../../../../org/apache/hadoop/hbase/procedure/TestProcedureDescriber.TestProcedure.html" title="class in org.apache.hadoop.hbase.procedure"><span class="typeNameLink">TestProcedureDescriber.TestProcedure</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure.<a href="../../../../../org/apache/hadoop/hbase/procedure/TestProcedure.LatchedProcedure.html" title="class in org.apache.hadoop.hbase.procedure"><span class="typeNameLink">TestProcedure.LatchedProcedure</span></a></li>
 </ul>
 </li>
-<li type="circle">org.apache.hadoop.hbase.procedure.Procedure (implements java.util.concurrent.<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html?is-external=true" title="class or interface in java.util.concurrent">Callable</a>&lt;V&gt;, org.apache.hadoop.hbase.errorhandling.ForeignExceptionListener)
+<li type="circle">org.apache.hadoop.hbase.procedure2.Procedure&lt;TEnvironment&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.procedure.<a href="../../../../../org/apache/hadoop/hbase/procedure/TestProcedure.LatchedProcedure.html" title="class in org.apache.hadoop.hbase.procedure"><span class="typeNameLink">TestProcedure.LatchedProcedure</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure.<a href="../../../../../org/apache/hadoop/hbase/procedure/TestProcedureDescriber.TestProcedure.html" title="class in org.apache.hadoop.hbase.procedure"><span class="typeNameLink">TestProcedureDescriber.TestProcedure</span></a></li>
 </ul>
 </li>
 <li type="circle">org.apache.hadoop.hbase.procedure.ProcedureManager
diff --git a/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
index f375dda..7310b7e 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
@@ -241,10 +241,10 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestStateMachineProcedure.TestSMProcedureState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestStateMachineProcedure.TestSMProcedureState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.TestStateMachineProcedure.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestProcedureRecovery.TestStateMachineProcedure.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestYieldProcedures.TestStateMachineProcedure.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestYieldProcedures.TestStateMachineProcedure.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestProcedureBypass.StuckStateMachineState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestProcedureBypass.StuckStateMachineState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/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>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
index e2c99dd..d0ad7d5 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
@@ -719,10 +719,10 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<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/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>
 <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/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/TestCacheOnWriteInSchema.CacheOnWriteType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestCacheOnWriteInSchema.CacheOnWriteType</span></a></li>
 </ul>
 </li>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html
index f96d8a9..0064c42 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 [...]
 <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/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/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/IntegrationTestLoadAndVerify.Counters.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestLoadAndVerify.Counters</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html
index 0612d72..45aafc7 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html
@@ -163,9 +163,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/FaultyFSLog.FailureType.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">FaultyFSLog.FailureType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/IOTestProvider.AllowedOperations.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">IOTestProvider.AllowedOperations</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/TestWALSplit.Corruptions.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">TestWALSplit.Corruptions</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/IOTestProvider.AllowedOperations.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">IOTestProvider.AllowedOperations</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/FaultyFSLog.FailureType.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">FaultyFSLog.FailureType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html
index c32f132..0fcef7a 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/TestMetaFixer.html
@@ -30,260 +30,355 @@
 <span class="sourceLineNo">022</span>import static org.junit.Assert.assertTrue;<a name="line.22"></a>
 <span class="sourceLineNo">023</span>import java.io.IOException;<a name="line.23"></a>
 <span class="sourceLineNo">024</span>import java.util.Collections;<a name="line.24"></a>
-<span class="sourceLineNo">025</span>import java.util.List;<a name="line.25"></a>
-<span class="sourceLineNo">026</span>import java.util.Map;<a name="line.26"></a>
-<span class="sourceLineNo">027</span>import java.util.function.BooleanSupplier;<a name="line.27"></a>
-<span class="sourceLineNo">028</span>import org.apache.hadoop.hbase.HBaseClassTestRule;<a name="line.28"></a>
-<span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.HBaseTestingUtility;<a name="line.29"></a>
-<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.HConstants;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.MetaTableAccessor;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.TableName;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.client.RegionInfoBuilder;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.client.Result;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.client.Table;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import org.apache.hadoop.hbase.master.assignment.GCRegionProcedure;<a name="line.37"></a>
-<span class="sourceLineNo">038</span>import org.apache.hadoop.hbase.master.assignment.GCMultipleMergedRegionsProcedure;<a name="line.38"></a>
-<span class="sourceLineNo">039</span>import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;<a name="line.39"></a>
-<span class="sourceLineNo">040</span>import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;<a name="line.40"></a>
-<span class="sourceLineNo">041</span>import org.apache.hadoop.hbase.testclassification.LargeTests;<a name="line.41"></a>
-<span class="sourceLineNo">042</span>import org.apache.hadoop.hbase.testclassification.MasterTests;<a name="line.42"></a>
-<span class="sourceLineNo">043</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.43"></a>
-<span class="sourceLineNo">044</span>import org.junit.AfterClass;<a name="line.44"></a>
-<span class="sourceLineNo">045</span>import org.junit.BeforeClass;<a name="line.45"></a>
-<span class="sourceLineNo">046</span>import org.junit.ClassRule;<a name="line.46"></a>
-<span class="sourceLineNo">047</span>import org.junit.Rule;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.junit.Test;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.junit.experimental.categories.Category;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.junit.rules.TestName;<a name="line.50"></a>
-<span class="sourceLineNo">051</span><a name="line.51"></a>
-<span class="sourceLineNo">052</span>@Category({MasterTests.class, LargeTests.class})<a name="line.52"></a>
-<span class="sourceLineNo">053</span>public class TestMetaFixer {<a name="line.53"></a>
-<span class="sourceLineNo">054</span>  @ClassRule<a name="line.54"></a>
-<span class="sourceLineNo">055</span>  public static final HBaseClassTestRule CLASS_RULE =<a name="line.55"></a>
-<span class="sourceLineNo">056</span>      HBaseClassTestRule.forClass(TestMetaFixer.class);<a name="line.56"></a>
-<span class="sourceLineNo">057</span>  @Rule<a name="line.57"></a>
-<span class="sourceLineNo">058</span>  public TestName name = new TestName();<a name="line.58"></a>
-<span class="sourceLineNo">059</span><a name="line.59"></a>
-<span class="sourceLineNo">060</span>  private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();<a name="line.60"></a>
-<span class="sourceLineNo">061</span><a name="line.61"></a>
-<span class="sourceLineNo">062</span>  @BeforeClass<a name="line.62"></a>
-<span class="sourceLineNo">063</span>  public static void setupBeforeClass() throws Exception {<a name="line.63"></a>
-<span class="sourceLineNo">064</span>    TEST_UTIL.startMiniCluster();<a name="line.64"></a>
-<span class="sourceLineNo">065</span>  }<a name="line.65"></a>
-<span class="sourceLineNo">066</span><a name="line.66"></a>
-<span class="sourceLineNo">067</span>  @AfterClass<a name="line.67"></a>
-<span class="sourceLineNo">068</span>  public static void tearDownAfterClass() throws Exception {<a name="line.68"></a>
-<span class="sourceLineNo">069</span>    TEST_UTIL.shutdownMiniCluster();<a name="line.69"></a>
-<span class="sourceLineNo">070</span>  }<a name="line.70"></a>
-<span class="sourceLineNo">071</span><a name="line.71"></a>
-<span class="sourceLineNo">072</span>  private void deleteRegion(MasterServices services, RegionInfo ri) throws IOException {<a name="line.72"></a>
-<span class="sourceLineNo">073</span>    MetaTableAccessor.deleteRegionInfo(TEST_UTIL.getConnection(), ri);<a name="line.73"></a>
-<span class="sourceLineNo">074</span>    // Delete it from Master context too else it sticks around.<a name="line.74"></a>
-<span class="sourceLineNo">075</span>    services.getAssignmentManager().getRegionStates().deleteRegion(ri);<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  }<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  @Test<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  public void testPlugsHoles() throws Exception {<a name="line.79"></a>
-<span class="sourceLineNo">080</span>    TableName tn = TableName.valueOf(this.name.getMethodName());<a name="line.80"></a>
-<span class="sourceLineNo">081</span>    TEST_UTIL.createMultiRegionTable(tn, HConstants.CATALOG_FAMILY);<a name="line.81"></a>
-<span class="sourceLineNo">082</span>    List&lt;RegionInfo&gt; ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);<a name="line.82"></a>
-<span class="sourceLineNo">083</span>    MasterServices services = TEST_UTIL.getHBaseCluster().getMaster();<a name="line.83"></a>
-<span class="sourceLineNo">084</span>    int initialSize = services.getAssignmentManager().getRegionStates().getRegionStates().size();<a name="line.84"></a>
-<span class="sourceLineNo">085</span>    services.getCatalogJanitor().scan();<a name="line.85"></a>
-<span class="sourceLineNo">086</span>    CatalogJanitor.Report report = services.getCatalogJanitor().getLastReport();<a name="line.86"></a>
-<span class="sourceLineNo">087</span>    assertTrue(report.isEmpty());<a name="line.87"></a>
-<span class="sourceLineNo">088</span>    int originalCount = ris.size();<a name="line.88"></a>
-<span class="sourceLineNo">089</span>    // Remove first, last and middle region. See if hole gets plugged. Table has 26 regions.<a name="line.89"></a>
-<span class="sourceLineNo">090</span>    deleteRegion(services, ris.get(ris.size() -1));<a name="line.90"></a>
-<span class="sourceLineNo">091</span>    deleteRegion(services, ris.get(3));<a name="line.91"></a>
-<span class="sourceLineNo">092</span>    deleteRegion(services, ris.get(0));<a name="line.92"></a>
-<span class="sourceLineNo">093</span>    assertEquals(initialSize - 3,<a name="line.93"></a>
-<span class="sourceLineNo">094</span>        services.getAssignmentManager().getRegionStates().getRegionStates().size());<a name="line.94"></a>
-<span class="sourceLineNo">095</span>    services.getCatalogJanitor().scan();<a name="line.95"></a>
-<span class="sourceLineNo">096</span>    report = services.getCatalogJanitor().getLastReport();<a name="line.96"></a>
-<span class="sourceLineNo">097</span>    assertEquals(report.toString(), 3, report.getHoles().size());<a name="line.97"></a>
-<span class="sourceLineNo">098</span>    MetaFixer fixer = new MetaFixer(services);<a name="line.98"></a>
-<span class="sourceLineNo">099</span>    fixer.fixHoles(report);<a name="line.99"></a>
-<span class="sourceLineNo">100</span>    services.getCatalogJanitor().scan();<a name="line.100"></a>
-<span class="sourceLineNo">101</span>    report = services.getCatalogJanitor().getLastReport();<a name="line.101"></a>
-<span class="sourceLineNo">102</span>    assertTrue(report.toString(), report.isEmpty());<a name="line.102"></a>
-<span class="sourceLineNo">103</span>    assertEquals(initialSize,<a name="line.103"></a>
-<span class="sourceLineNo">104</span>        services.getAssignmentManager().getRegionStates().getRegionStates().size());<a name="line.104"></a>
-<span class="sourceLineNo">105</span><a name="line.105"></a>
-<span class="sourceLineNo">106</span>    // wait for RITs to settle -- those are the fixed regions being assigned -- or until the<a name="line.106"></a>
-<span class="sourceLineNo">107</span>    // watchdog TestRule terminates the test.<a name="line.107"></a>
-<span class="sourceLineNo">108</span>    await(50, () -&gt; isNotEmpty(services.getAssignmentManager().getRegionsInTransition()));<a name="line.108"></a>
+<span class="sourceLineNo">025</span>import java.util.HashSet;<a name="line.25"></a>
+<span class="sourceLineNo">026</span>import java.util.List;<a name="line.26"></a>
+<span class="sourceLineNo">027</span>import java.util.Map;<a name="line.27"></a>
+<span class="sourceLineNo">028</span>import java.util.function.BooleanSupplier;<a name="line.28"></a>
+<span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.HBaseClassTestRule;<a name="line.29"></a>
+<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.HBaseTestingUtility;<a name="line.30"></a>
+<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.HConstants;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.MetaTableAccessor;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.TableName;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.client.RegionInfoBuilder;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.client.Result;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import org.apache.hadoop.hbase.client.Table;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import org.apache.hadoop.hbase.master.assignment.AssignmentManager;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import org.apache.hadoop.hbase.master.assignment.GCRegionProcedure;<a name="line.39"></a>
+<span class="sourceLineNo">040</span>import org.apache.hadoop.hbase.master.assignment.GCMultipleMergedRegionsProcedure;<a name="line.40"></a>
+<span class="sourceLineNo">041</span>import org.apache.hadoop.hbase.master.assignment.RegionStates;<a name="line.41"></a>
+<span class="sourceLineNo">042</span>import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;<a name="line.42"></a>
+<span class="sourceLineNo">043</span>import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;<a name="line.43"></a>
+<span class="sourceLineNo">044</span>import org.apache.hadoop.hbase.testclassification.LargeTests;<a name="line.44"></a>
+<span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.testclassification.MasterTests;<a name="line.45"></a>
+<span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.util.Pair;<a name="line.46"></a>
+<span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.47"></a>
+<span class="sourceLineNo">048</span>import org.junit.AfterClass;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.junit.BeforeClass;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.junit.ClassRule;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.junit.Rule;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.junit.Test;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.junit.experimental.categories.Category;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.junit.rules.TestName;<a name="line.54"></a>
+<span class="sourceLineNo">055</span><a name="line.55"></a>
+<span class="sourceLineNo">056</span>@Category({MasterTests.class, LargeTests.class})<a name="line.56"></a>
+<span class="sourceLineNo">057</span>public class TestMetaFixer {<a name="line.57"></a>
+<span class="sourceLineNo">058</span>  @ClassRule<a name="line.58"></a>
+<span class="sourceLineNo">059</span>  public static final HBaseClassTestRule CLASS_RULE =<a name="line.59"></a>
+<span class="sourceLineNo">060</span>      HBaseClassTestRule.forClass(TestMetaFixer.class);<a name="line.60"></a>
+<span class="sourceLineNo">061</span>  @Rule<a name="line.61"></a>
+<span class="sourceLineNo">062</span>  public TestName name = new TestName();<a name="line.62"></a>
+<span class="sourceLineNo">063</span><a name="line.63"></a>
+<span class="sourceLineNo">064</span>  private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();<a name="line.64"></a>
+<span class="sourceLineNo">065</span><a name="line.65"></a>
+<span class="sourceLineNo">066</span>  @BeforeClass<a name="line.66"></a>
+<span class="sourceLineNo">067</span>  public static void setupBeforeClass() throws Exception {<a name="line.67"></a>
+<span class="sourceLineNo">068</span>    TEST_UTIL.startMiniCluster();<a name="line.68"></a>
+<span class="sourceLineNo">069</span>  }<a name="line.69"></a>
+<span class="sourceLineNo">070</span><a name="line.70"></a>
+<span class="sourceLineNo">071</span>  @AfterClass<a name="line.71"></a>
+<span class="sourceLineNo">072</span>  public static void tearDownAfterClass() throws Exception {<a name="line.72"></a>
+<span class="sourceLineNo">073</span>    TEST_UTIL.shutdownMiniCluster();<a name="line.73"></a>
+<span class="sourceLineNo">074</span>  }<a name="line.74"></a>
+<span class="sourceLineNo">075</span><a name="line.75"></a>
+<span class="sourceLineNo">076</span>  private void deleteRegion(MasterServices services, RegionInfo ri) throws IOException {<a name="line.76"></a>
+<span class="sourceLineNo">077</span>    MetaTableAccessor.deleteRegionInfo(TEST_UTIL.getConnection(), ri);<a name="line.77"></a>
+<span class="sourceLineNo">078</span>    // Delete it from Master context too else it sticks around.<a name="line.78"></a>
+<span class="sourceLineNo">079</span>    services.getAssignmentManager().getRegionStates().deleteRegion(ri);<a name="line.79"></a>
+<span class="sourceLineNo">080</span>  }<a name="line.80"></a>
+<span class="sourceLineNo">081</span><a name="line.81"></a>
+<span class="sourceLineNo">082</span>  @Test<a name="line.82"></a>
+<span class="sourceLineNo">083</span>  public void testPlugsHoles() throws Exception {<a name="line.83"></a>
+<span class="sourceLineNo">084</span>    TableName tn = TableName.valueOf(this.name.getMethodName());<a name="line.84"></a>
+<span class="sourceLineNo">085</span>    TEST_UTIL.createMultiRegionTable(tn, HConstants.CATALOG_FAMILY);<a name="line.85"></a>
+<span class="sourceLineNo">086</span>    List&lt;RegionInfo&gt; ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);<a name="line.86"></a>
+<span class="sourceLineNo">087</span>    MasterServices services = TEST_UTIL.getHBaseCluster().getMaster();<a name="line.87"></a>
+<span class="sourceLineNo">088</span>    int initialSize = services.getAssignmentManager().getRegionStates().getRegionStates().size();<a name="line.88"></a>
+<span class="sourceLineNo">089</span>    services.getCatalogJanitor().scan();<a name="line.89"></a>
+<span class="sourceLineNo">090</span>    CatalogJanitor.Report report = services.getCatalogJanitor().getLastReport();<a name="line.90"></a>
+<span class="sourceLineNo">091</span>    assertTrue(report.isEmpty());<a name="line.91"></a>
+<span class="sourceLineNo">092</span>    int originalCount = ris.size();<a name="line.92"></a>
+<span class="sourceLineNo">093</span>    // Remove first, last and middle region. See if hole gets plugged. Table has 26 regions.<a name="line.93"></a>
+<span class="sourceLineNo">094</span>    deleteRegion(services, ris.get(ris.size() -1));<a name="line.94"></a>
+<span class="sourceLineNo">095</span>    deleteRegion(services, ris.get(3));<a name="line.95"></a>
+<span class="sourceLineNo">096</span>    deleteRegion(services, ris.get(0));<a name="line.96"></a>
+<span class="sourceLineNo">097</span>    assertEquals(initialSize - 3,<a name="line.97"></a>
+<span class="sourceLineNo">098</span>        services.getAssignmentManager().getRegionStates().getRegionStates().size());<a name="line.98"></a>
+<span class="sourceLineNo">099</span>    services.getCatalogJanitor().scan();<a name="line.99"></a>
+<span class="sourceLineNo">100</span>    report = services.getCatalogJanitor().getLastReport();<a name="line.100"></a>
+<span class="sourceLineNo">101</span>    assertEquals(report.toString(), 3, report.getHoles().size());<a name="line.101"></a>
+<span class="sourceLineNo">102</span>    MetaFixer fixer = new MetaFixer(services);<a name="line.102"></a>
+<span class="sourceLineNo">103</span>    fixer.fixHoles(report);<a name="line.103"></a>
+<span class="sourceLineNo">104</span>    services.getCatalogJanitor().scan();<a name="line.104"></a>
+<span class="sourceLineNo">105</span>    report = services.getCatalogJanitor().getLastReport();<a name="line.105"></a>
+<span class="sourceLineNo">106</span>    assertTrue(report.toString(), report.isEmpty());<a name="line.106"></a>
+<span class="sourceLineNo">107</span>    assertEquals(initialSize,<a name="line.107"></a>
+<span class="sourceLineNo">108</span>        services.getAssignmentManager().getRegionStates().getRegionStates().size());<a name="line.108"></a>
 <span class="sourceLineNo">109</span><a name="line.109"></a>
-<span class="sourceLineNo">110</span>    ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);<a name="line.110"></a>
-<span class="sourceLineNo">111</span>    assertEquals(originalCount, ris.size());<a name="line.111"></a>
-<span class="sourceLineNo">112</span>  }<a name="line.112"></a>
+<span class="sourceLineNo">110</span>    // wait for RITs to settle -- those are the fixed regions being assigned -- or until the<a name="line.110"></a>
+<span class="sourceLineNo">111</span>    // watchdog TestRule terminates the test.<a name="line.111"></a>
+<span class="sourceLineNo">112</span>    await(50, () -&gt; isNotEmpty(services.getAssignmentManager().getRegionsInTransition()));<a name="line.112"></a>
 <span class="sourceLineNo">113</span><a name="line.113"></a>
-<span class="sourceLineNo">114</span>  /**<a name="line.114"></a>
-<span class="sourceLineNo">115</span>   * Just make sure running fixMeta does right thing for the case<a name="line.115"></a>
-<span class="sourceLineNo">116</span>   * of a single-region Table where the region gets dropped.<a name="line.116"></a>
-<span class="sourceLineNo">117</span>   * There is nothing much we can do. We can't restore what<a name="line.117"></a>
-<span class="sourceLineNo">118</span>   * we don't know about (at least from a read of hbase:meta).<a name="line.118"></a>
-<span class="sourceLineNo">119</span>   */<a name="line.119"></a>
-<span class="sourceLineNo">120</span>  @Test<a name="line.120"></a>
-<span class="sourceLineNo">121</span>  public void testOneRegionTable() throws IOException {<a name="line.121"></a>
-<span class="sourceLineNo">122</span>    TableName tn = TableName.valueOf(this.name.getMethodName());<a name="line.122"></a>
-<span class="sourceLineNo">123</span>    TEST_UTIL.createTable(tn, HConstants.CATALOG_FAMILY);<a name="line.123"></a>
-<span class="sourceLineNo">124</span>    List&lt;RegionInfo&gt; ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);<a name="line.124"></a>
-<span class="sourceLineNo">125</span>    MasterServices services = TEST_UTIL.getHBaseCluster().getMaster();<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    services.getCatalogJanitor().scan();<a name="line.126"></a>
-<span class="sourceLineNo">127</span>    deleteRegion(services, ris.get(0));<a name="line.127"></a>
-<span class="sourceLineNo">128</span>    services.getCatalogJanitor().scan();<a name="line.128"></a>
-<span class="sourceLineNo">129</span>    CatalogJanitor.Report report = services.getCatalogJanitor().getLastReport();<a name="line.129"></a>
-<span class="sourceLineNo">130</span>    ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);<a name="line.130"></a>
-<span class="sourceLineNo">131</span>    assertTrue(ris.isEmpty());<a name="line.131"></a>
-<span class="sourceLineNo">132</span>    MetaFixer fixer = new MetaFixer(services);<a name="line.132"></a>
-<span class="sourceLineNo">133</span>    fixer.fixHoles(report);<a name="line.133"></a>
-<span class="sourceLineNo">134</span>    report = services.getCatalogJanitor().getLastReport();<a name="line.134"></a>
-<span class="sourceLineNo">135</span>    assertTrue(report.isEmpty());<a name="line.135"></a>
-<span class="sourceLineNo">136</span>    ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);<a name="line.136"></a>
-<span class="sourceLineNo">137</span>    assertEquals(0, ris.size());<a name="line.137"></a>
-<span class="sourceLineNo">138</span>  }<a name="line.138"></a>
-<span class="sourceLineNo">139</span><a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private static void makeOverlap(MasterServices services, RegionInfo a, RegionInfo b)<a name="line.140"></a>
-<span class="sourceLineNo">141</span>      throws IOException {<a name="line.141"></a>
-<span class="sourceLineNo">142</span>    RegionInfo overlapRegion = RegionInfoBuilder.newBuilder(a.getTable()).<a name="line.142"></a>
-<span class="sourceLineNo">143</span>        setStartKey(a.getStartKey()).<a name="line.143"></a>
-<span class="sourceLineNo">144</span>        setEndKey(b.getEndKey()).<a name="line.144"></a>
-<span class="sourceLineNo">145</span>        build();<a name="line.145"></a>
-<span class="sourceLineNo">146</span>    MetaTableAccessor.putsToMetaTable(services.getConnection(),<a name="line.146"></a>
-<span class="sourceLineNo">147</span>        Collections.singletonList(MetaTableAccessor.makePutFromRegionInfo(overlapRegion,<a name="line.147"></a>
-<span class="sourceLineNo">148</span>            System.currentTimeMillis())));<a name="line.148"></a>
-<span class="sourceLineNo">149</span>    // TODO: Add checks at assign time to PREVENT being able to assign over existing assign.<a name="line.149"></a>
-<span class="sourceLineNo">150</span>    services.getAssignmentManager().assign(overlapRegion);<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  }<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  @Test<a name="line.153"></a>
-<span class="sourceLineNo">154</span>  public void testOverlap() throws Exception {<a name="line.154"></a>
-<span class="sourceLineNo">155</span>    TableName tn = TableName.valueOf(this.name.getMethodName());<a name="line.155"></a>
-<span class="sourceLineNo">156</span>    Table t = TEST_UTIL.createMultiRegionTable(tn, HConstants.CATALOG_FAMILY);<a name="line.156"></a>
-<span class="sourceLineNo">157</span>    TEST_UTIL.loadTable(t, HConstants.CATALOG_FAMILY);<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    List&lt;RegionInfo&gt; ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);<a name="line.158"></a>
-<span class="sourceLineNo">159</span>    assertTrue(ris.size() &gt; 5);<a name="line.159"></a>
-<span class="sourceLineNo">160</span>    HMaster services = TEST_UTIL.getHBaseCluster().getMaster();<a name="line.160"></a>
-<span class="sourceLineNo">161</span>    HbckChore hbckChore = services.getHbckChore();<a name="line.161"></a>
-<span class="sourceLineNo">162</span>    services.getCatalogJanitor().scan();<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    CatalogJanitor.Report report = services.getCatalogJanitor().getLastReport();<a name="line.163"></a>
-<span class="sourceLineNo">164</span>    assertTrue(report.isEmpty());<a name="line.164"></a>
-<span class="sourceLineNo">165</span>    // Make a simple overlap spanning second and third region.<a name="line.165"></a>
-<span class="sourceLineNo">166</span>    makeOverlap(services, ris.get(1), ris.get(3));<a name="line.166"></a>
-<span class="sourceLineNo">167</span>    makeOverlap(services, ris.get(2), ris.get(3));<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    makeOverlap(services, ris.get(2), ris.get(4));<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    Threads.sleep(10000);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    services.getCatalogJanitor().scan();<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    report = services.getCatalogJanitor().getLastReport();<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    assertEquals(6, report.getOverlaps().size());<a name="line.172"></a>
-<span class="sourceLineNo">173</span>    assertEquals(1, MetaFixer.calculateMerges(10, report.getOverlaps()).size());<a name="line.173"></a>
-<span class="sourceLineNo">174</span>    MetaFixer fixer = new MetaFixer(services);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    fixer.fixOverlaps(report);<a name="line.175"></a>
-<span class="sourceLineNo">176</span><a name="line.176"></a>
-<span class="sourceLineNo">177</span>    CatalogJanitor cj = services.getCatalogJanitor();<a name="line.177"></a>
-<span class="sourceLineNo">178</span>    await(10, () -&gt; {<a name="line.178"></a>
-<span class="sourceLineNo">179</span>      try {<a name="line.179"></a>
-<span class="sourceLineNo">180</span>        if (cj.scan() &gt; 0) {<a name="line.180"></a>
-<span class="sourceLineNo">181</span>          // It submits GC once, then it will immediately kick off another GC to test if<a name="line.181"></a>
-<span class="sourceLineNo">182</span>          // GCMultipleMergedRegionsProcedure is idempotent. If it is not, it will create<a name="line.182"></a>
-<span class="sourceLineNo">183</span>          // a hole.<a name="line.183"></a>
-<span class="sourceLineNo">184</span>          Map&lt;RegionInfo, Result&gt; mergedRegions = cj.getLastReport().mergedRegions;<a name="line.184"></a>
-<span class="sourceLineNo">185</span>          for (Map.Entry&lt;RegionInfo, Result&gt; e : mergedRegions.entrySet()) {<a name="line.185"></a>
-<span class="sourceLineNo">186</span>            List&lt;RegionInfo&gt; parents = MetaTableAccessor.getMergeRegions(e.getValue().rawCells());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>            if (parents != null) {<a name="line.187"></a>
-<span class="sourceLineNo">188</span>              ProcedureExecutor&lt;MasterProcedureEnv&gt; pe = services.getMasterProcedureExecutor();<a name="line.188"></a>
-<span class="sourceLineNo">189</span>              pe.submitProcedure(new GCMultipleMergedRegionsProcedure(pe.getEnvironment(),<a name="line.189"></a>
-<span class="sourceLineNo">190</span>                e.getKey(), parents));<a name="line.190"></a>
-<span class="sourceLineNo">191</span>            }<a name="line.191"></a>
-<span class="sourceLineNo">192</span>          }<a name="line.192"></a>
-<span class="sourceLineNo">193</span>          return true;<a name="line.193"></a>
-<span class="sourceLineNo">194</span>        }<a name="line.194"></a>
-<span class="sourceLineNo">195</span>        return false;<a name="line.195"></a>
-<span class="sourceLineNo">196</span>      } catch (Exception e) {<a name="line.196"></a>
-<span class="sourceLineNo">197</span>        throw new RuntimeException(e);<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><a name="line.200"></a>
-<span class="sourceLineNo">201</span>    // Wait until all GCs settled down<a name="line.201"></a>
-<span class="sourceLineNo">202</span>    await(10, () -&gt; {<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      return services.getMasterProcedureExecutor().getActiveProcIds().isEmpty();<a name="line.203"></a>
-<span class="sourceLineNo">204</span>    });<a name="line.204"></a>
-<span class="sourceLineNo">205</span><a name="line.205"></a>
-<span class="sourceLineNo">206</span>    // No orphan regions on FS<a name="line.206"></a>
-<span class="sourceLineNo">207</span>    hbckChore.chore();<a name="line.207"></a>
-<span class="sourceLineNo">208</span>    assertEquals(0, hbckChore.getOrphanRegionsOnFS().size());<a name="line.208"></a>
-<span class="sourceLineNo">209</span><a name="line.209"></a>
-<span class="sourceLineNo">210</span>    // No holes reported.<a name="line.210"></a>
-<span class="sourceLineNo">211</span>    cj.scan();<a name="line.211"></a>
-<span class="sourceLineNo">212</span>    final CatalogJanitor.Report postReport = cj.getLastReport();<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    assertTrue(postReport.isEmpty());<a name="line.213"></a>
-<span class="sourceLineNo">214</span>  }<a name="line.214"></a>
-<span class="sourceLineNo">215</span><a name="line.215"></a>
-<span class="sourceLineNo">216</span>  /**<a name="line.216"></a>
-<span class="sourceLineNo">217</span>   * Make it so a big overlap spans many Regions, some of which are non-contiguous. Make it so<a name="line.217"></a>
-<span class="sourceLineNo">218</span>   * we can fix this condition. HBASE-24247<a name="line.218"></a>
-<span class="sourceLineNo">219</span>   */<a name="line.219"></a>
-<span class="sourceLineNo">220</span>  @Test<a name="line.220"></a>
-<span class="sourceLineNo">221</span>  public void testOverlapWithMergeOfNonContiguous() throws Exception {<a name="line.221"></a>
-<span class="sourceLineNo">222</span>    TableName tn = TableName.valueOf(this.name.getMethodName());<a name="line.222"></a>
-<span class="sourceLineNo">223</span>    TEST_UTIL.createMultiRegionTable(tn, HConstants.CATALOG_FAMILY);<a name="line.223"></a>
-<span class="sourceLineNo">224</span>    List&lt;RegionInfo&gt; ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);<a name="line.224"></a>
-<span class="sourceLineNo">225</span>    assertTrue(ris.size() &gt; 5);<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    MasterServices services = TEST_UTIL.getHBaseCluster().getMaster();<a name="line.226"></a>
-<span class="sourceLineNo">227</span>    services.getCatalogJanitor().scan();<a name="line.227"></a>
-<span class="sourceLineNo">228</span>    CatalogJanitor.Report report = services.getCatalogJanitor().getLastReport();<a name="line.228"></a>
-<span class="sourceLineNo">229</span>    assertTrue(report.isEmpty());<a name="line.229"></a>
-<span class="sourceLineNo">230</span>    // Make a simple overlap spanning second and third region.<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    makeOverlap(services, ris.get(1), ris.get(5));<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    // Now Delete a region under the overlap to manufacture non-contiguous sub regions.<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    RegionInfo deletedRegion = ris.get(3);<a name="line.233"></a>
-<span class="sourceLineNo">234</span>    long pid = services.getAssignmentManager().unassign(deletedRegion);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    while (!services.getMasterProcedureExecutor().isFinished(pid)) {<a name="line.235"></a>
-<span class="sourceLineNo">236</span>      Threads.sleep(100);<a name="line.236"></a>
-<span class="sourceLineNo">237</span>    }<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    GCRegionProcedure procedure =<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      new GCRegionProcedure(services.getMasterProcedureExecutor().getEnvironment(), ris.get(3));<a name="line.239"></a>
-<span class="sourceLineNo">240</span>    pid = services.getMasterProcedureExecutor().submitProcedure(procedure);<a name="line.240"></a>
-<span class="sourceLineNo">241</span>    while (!services.getMasterProcedureExecutor().isFinished(pid)) {<a name="line.241"></a>
-<span class="sourceLineNo">242</span>      Threads.sleep(100);<a name="line.242"></a>
-<span class="sourceLineNo">243</span>    }<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    Threads.sleep(10000);<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    services.getCatalogJanitor().scan();<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    report = services.getCatalogJanitor().getLastReport();<a name="line.246"></a>
-<span class="sourceLineNo">247</span>    assertEquals(1, MetaFixer.calculateMerges(10, report.getOverlaps()).size());<a name="line.247"></a>
-<span class="sourceLineNo">248</span>    MetaFixer fixer = new MetaFixer(services);<a name="line.248"></a>
-<span class="sourceLineNo">249</span>    fixer.fixOverlaps(report);<a name="line.249"></a>
-<span class="sourceLineNo">250</span>    await(10, () -&gt; {<a name="line.250"></a>
-<span class="sourceLineNo">251</span>      try {<a name="line.251"></a>
-<span class="sourceLineNo">252</span>        services.getCatalogJanitor().scan();<a name="line.252"></a>
-<span class="sourceLineNo">253</span>        final CatalogJanitor.Report postReport = services.getCatalogJanitor().getLastReport();<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        return postReport.isEmpty();<a name="line.254"></a>
-<span class="sourceLineNo">255</span>      } catch (Exception e) {<a name="line.255"></a>
-<span class="sourceLineNo">256</span>        throw new RuntimeException(e);<a name="line.256"></a>
-<span class="sourceLineNo">257</span>      }<a name="line.257"></a>
-<span class="sourceLineNo">258</span>    });<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  }<a name="line.259"></a>
-<span class="sourceLineNo">260</span><a name="line.260"></a>
-<span class="sourceLineNo">261</span>  /**<a name="line.261"></a>
-<span class="sourceLineNo">262</span>   * Await the successful return of {@code condition}, sleeping {@code sleepMillis} between<a name="line.262"></a>
-<span class="sourceLineNo">263</span>   * invocations.<a name="line.263"></a>
-<span class="sourceLineNo">264</span>   */<a name="line.264"></a>
-<span class="sourceLineNo">265</span>  private static void await(final long sleepMillis, final BooleanSupplier condition)<a name="line.265"></a>
-<span class="sourceLineNo">266</span>    throws InterruptedException {<a name="line.266"></a>
-<span class="sourceLineNo">267</span>    try {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>      while (!condition.getAsBoolean()) {<a name="line.268"></a>
-<span class="sourceLineNo">269</span>        Thread.sleep(sleepMillis);<a name="line.269"></a>
-<span class="sourceLineNo">270</span>      }<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    } catch (RuntimeException e) {<a name="line.271"></a>
-<span class="sourceLineNo">272</span>      if (e.getCause() instanceof AssertionError) {<a name="line.272"></a>
-<span class="sourceLineNo">273</span>        throw (AssertionError) e.getCause();<a name="line.273"></a>
-<span class="sourceLineNo">274</span>      }<a name="line.274"></a>
-<span class="sourceLineNo">275</span>      throw e;<a name="line.275"></a>
-<span class="sourceLineNo">276</span>    }<a name="line.276"></a>
-<span class="sourceLineNo">277</span>  }<a name="line.277"></a>
-<span class="sourceLineNo">278</span>}<a name="line.278"></a>
+<span class="sourceLineNo">114</span>    ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);<a name="line.114"></a>
+<span class="sourceLineNo">115</span>    assertEquals(originalCount, ris.size());<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>   * Just make sure running fixMeta does right thing for the case<a name="line.119"></a>
+<span class="sourceLineNo">120</span>   * of a single-region Table where the region gets dropped.<a name="line.120"></a>
+<span class="sourceLineNo">121</span>   * There is nothing much we can do. We can't restore what<a name="line.121"></a>
+<span class="sourceLineNo">122</span>   * we don't know about (at least from a read of hbase:meta).<a name="line.122"></a>
+<span class="sourceLineNo">123</span>   */<a name="line.123"></a>
+<span class="sourceLineNo">124</span>  @Test<a name="line.124"></a>
+<span class="sourceLineNo">125</span>  public void testOneRegionTable() throws IOException {<a name="line.125"></a>
+<span class="sourceLineNo">126</span>    TableName tn = TableName.valueOf(this.name.getMethodName());<a name="line.126"></a>
+<span class="sourceLineNo">127</span>    TEST_UTIL.createTable(tn, HConstants.CATALOG_FAMILY);<a name="line.127"></a>
+<span class="sourceLineNo">128</span>    List&lt;RegionInfo&gt; ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);<a name="line.128"></a>
+<span class="sourceLineNo">129</span>    MasterServices services = TEST_UTIL.getHBaseCluster().getMaster();<a name="line.129"></a>
+<span class="sourceLineNo">130</span>    services.getCatalogJanitor().scan();<a name="line.130"></a>
+<span class="sourceLineNo">131</span>    deleteRegion(services, ris.get(0));<a name="line.131"></a>
+<span class="sourceLineNo">132</span>    services.getCatalogJanitor().scan();<a name="line.132"></a>
+<span class="sourceLineNo">133</span>    CatalogJanitor.Report report = services.getCatalogJanitor().getLastReport();<a name="line.133"></a>
+<span class="sourceLineNo">134</span>    ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    assertTrue(ris.isEmpty());<a name="line.135"></a>
+<span class="sourceLineNo">136</span>    MetaFixer fixer = new MetaFixer(services);<a name="line.136"></a>
+<span class="sourceLineNo">137</span>    fixer.fixHoles(report);<a name="line.137"></a>
+<span class="sourceLineNo">138</span>    report = services.getCatalogJanitor().getLastReport();<a name="line.138"></a>
+<span class="sourceLineNo">139</span>    assertTrue(report.isEmpty());<a name="line.139"></a>
+<span class="sourceLineNo">140</span>    ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);<a name="line.140"></a>
+<span class="sourceLineNo">141</span>    assertEquals(0, ris.size());<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>  private static void makeOverlap(MasterServices services, RegionInfo a, RegionInfo b)<a name="line.144"></a>
+<span class="sourceLineNo">145</span>      throws IOException {<a name="line.145"></a>
+<span class="sourceLineNo">146</span>    RegionInfo overlapRegion = RegionInfoBuilder.newBuilder(a.getTable()).<a name="line.146"></a>
+<span class="sourceLineNo">147</span>        setStartKey(a.getStartKey()).<a name="line.147"></a>
+<span class="sourceLineNo">148</span>        setEndKey(b.getEndKey()).<a name="line.148"></a>
+<span class="sourceLineNo">149</span>        build();<a name="line.149"></a>
+<span class="sourceLineNo">150</span>    MetaTableAccessor.putsToMetaTable(services.getConnection(),<a name="line.150"></a>
+<span class="sourceLineNo">151</span>        Collections.singletonList(MetaTableAccessor.makePutFromRegionInfo(overlapRegion,<a name="line.151"></a>
+<span class="sourceLineNo">152</span>            System.currentTimeMillis())));<a name="line.152"></a>
+<span class="sourceLineNo">153</span>    // TODO: Add checks at assign time to PREVENT being able to assign over existing assign.<a name="line.153"></a>
+<span class="sourceLineNo">154</span>    services.getAssignmentManager().assign(overlapRegion);<a name="line.154"></a>
+<span class="sourceLineNo">155</span>  }<a name="line.155"></a>
+<span class="sourceLineNo">156</span><a name="line.156"></a>
+<span class="sourceLineNo">157</span>  private void testOverlapCommon(final TableName tn) throws Exception {<a name="line.157"></a>
+<span class="sourceLineNo">158</span>    Table t = TEST_UTIL.createMultiRegionTable(tn, HConstants.CATALOG_FAMILY);<a name="line.158"></a>
+<span class="sourceLineNo">159</span>    TEST_UTIL.loadTable(t, HConstants.CATALOG_FAMILY);<a name="line.159"></a>
+<span class="sourceLineNo">160</span>    List&lt;RegionInfo&gt; ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);<a name="line.160"></a>
+<span class="sourceLineNo">161</span>    assertTrue(ris.size() &gt; 5);<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    HMaster services = TEST_UTIL.getHBaseCluster().getMaster();<a name="line.162"></a>
+<span class="sourceLineNo">163</span>    services.getCatalogJanitor().scan();<a name="line.163"></a>
+<span class="sourceLineNo">164</span>    CatalogJanitor.Report report = services.getCatalogJanitor().getLastReport();<a name="line.164"></a>
+<span class="sourceLineNo">165</span>    assertTrue(report.isEmpty());<a name="line.165"></a>
+<span class="sourceLineNo">166</span>    // Make a simple overlap spanning second and third region.<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    makeOverlap(services, ris.get(1), ris.get(3));<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    makeOverlap(services, ris.get(2), ris.get(3));<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    makeOverlap(services, ris.get(2), ris.get(4));<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    Threads.sleep(10000);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>  }<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>  @Test<a name="line.173"></a>
+<span class="sourceLineNo">174</span>  public void testOverlap() throws Exception {<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    TableName tn = TableName.valueOf(this.name.getMethodName());<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    testOverlapCommon(tn);<a name="line.176"></a>
+<span class="sourceLineNo">177</span>    HMaster services = TEST_UTIL.getHBaseCluster().getMaster();<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    HbckChore hbckChore = services.getHbckChore();<a name="line.178"></a>
+<span class="sourceLineNo">179</span><a name="line.179"></a>
+<span class="sourceLineNo">180</span>    CatalogJanitor cj = services.getCatalogJanitor();<a name="line.180"></a>
+<span class="sourceLineNo">181</span>    cj.scan();<a name="line.181"></a>
+<span class="sourceLineNo">182</span>    CatalogJanitor.Report report = cj.getLastReport();<a name="line.182"></a>
+<span class="sourceLineNo">183</span>    assertEquals(6, report.getOverlaps().size());<a name="line.183"></a>
+<span class="sourceLineNo">184</span>    assertEquals(1,<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      MetaFixer.calculateMerges(10, report.getOverlaps()).size());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>    MetaFixer fixer = new MetaFixer(services);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>    fixer.fixOverlaps(report);<a name="line.187"></a>
+<span class="sourceLineNo">188</span><a name="line.188"></a>
+<span class="sourceLineNo">189</span>    await(10, () -&gt; {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      try {<a name="line.190"></a>
+<span class="sourceLineNo">191</span>        if (cj.scan() &gt; 0) {<a name="line.191"></a>
+<span class="sourceLineNo">192</span>          // It submits GC once, then it will immediately kick off another GC to test if<a name="line.192"></a>
+<span class="sourceLineNo">193</span>          // GCMultipleMergedRegionsProcedure is idempotent. If it is not, it will create<a name="line.193"></a>
+<span class="sourceLineNo">194</span>          // a hole.<a name="line.194"></a>
+<span class="sourceLineNo">195</span>          Map&lt;RegionInfo, Result&gt; mergedRegions = cj.getLastReport().mergedRegions;<a name="line.195"></a>
+<span class="sourceLineNo">196</span>          for (Map.Entry&lt;RegionInfo, Result&gt; e : mergedRegions.entrySet()) {<a name="line.196"></a>
+<span class="sourceLineNo">197</span>            List&lt;RegionInfo&gt; parents = MetaTableAccessor.getMergeRegions(e.getValue().rawCells());<a name="line.197"></a>
+<span class="sourceLineNo">198</span>            if (parents != null) {<a name="line.198"></a>
+<span class="sourceLineNo">199</span>              ProcedureExecutor&lt;MasterProcedureEnv&gt; pe = services.getMasterProcedureExecutor();<a name="line.199"></a>
+<span class="sourceLineNo">200</span>              pe.submitProcedure(new GCMultipleMergedRegionsProcedure(pe.getEnvironment(),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>                e.getKey(), parents));<a name="line.201"></a>
+<span class="sourceLineNo">202</span>            }<a name="line.202"></a>
+<span class="sourceLineNo">203</span>          }<a name="line.203"></a>
+<span class="sourceLineNo">204</span>          return true;<a name="line.204"></a>
+<span class="sourceLineNo">205</span>        }<a name="line.205"></a>
+<span class="sourceLineNo">206</span>        return false;<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      } catch (Exception e) {<a name="line.207"></a>
+<span class="sourceLineNo">208</span>        throw new RuntimeException(e);<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      }<a name="line.209"></a>
+<span class="sourceLineNo">210</span>    });<a name="line.210"></a>
+<span class="sourceLineNo">211</span><a name="line.211"></a>
+<span class="sourceLineNo">212</span>    // Wait until all GCs settled down<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    await(10, () -&gt; {<a name="line.213"></a>
+<span class="sourceLineNo">214</span>      return services.getMasterProcedureExecutor().getActiveProcIds().isEmpty();<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    });<a name="line.215"></a>
+<span class="sourceLineNo">216</span><a name="line.216"></a>
+<span class="sourceLineNo">217</span>    // No orphan regions on FS<a name="line.217"></a>
+<span class="sourceLineNo">218</span>    hbckChore.chore();<a name="line.218"></a>
+<span class="sourceLineNo">219</span>    assertEquals(0, hbckChore.getOrphanRegionsOnFS().size());<a name="line.219"></a>
+<span class="sourceLineNo">220</span><a name="line.220"></a>
+<span class="sourceLineNo">221</span>    // No holes reported.<a name="line.221"></a>
+<span class="sourceLineNo">222</span>    cj.scan();<a name="line.222"></a>
+<span class="sourceLineNo">223</span>    final CatalogJanitor.Report postReport = cj.getLastReport();<a name="line.223"></a>
+<span class="sourceLineNo">224</span>    assertTrue(postReport.isEmpty());<a name="line.224"></a>
+<span class="sourceLineNo">225</span>  }<a name="line.225"></a>
+<span class="sourceLineNo">226</span><a name="line.226"></a>
+<span class="sourceLineNo">227</span>  @Test<a name="line.227"></a>
+<span class="sourceLineNo">228</span>  public void testOverlapWithSmallMergeCount() throws Exception {<a name="line.228"></a>
+<span class="sourceLineNo">229</span>    TableName tn = TableName.valueOf(this.name.getMethodName());<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    try {<a name="line.230"></a>
+<span class="sourceLineNo">231</span>      testOverlapCommon(tn);<a name="line.231"></a>
+<span class="sourceLineNo">232</span>      HMaster services = TEST_UTIL.getHBaseCluster().getMaster();<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      CatalogJanitor cj = services.getCatalogJanitor();<a name="line.233"></a>
+<span class="sourceLineNo">234</span>      cj.scan();<a name="line.234"></a>
+<span class="sourceLineNo">235</span>      CatalogJanitor.Report report = cj.getLastReport();<a name="line.235"></a>
+<span class="sourceLineNo">236</span>      assertEquals(6, report.getOverlaps().size());<a name="line.236"></a>
+<span class="sourceLineNo">237</span>      assertEquals(2,<a name="line.237"></a>
+<span class="sourceLineNo">238</span>        MetaFixer.calculateMerges(5, report.getOverlaps()).size());<a name="line.238"></a>
+<span class="sourceLineNo">239</span><a name="line.239"></a>
+<span class="sourceLineNo">240</span>      // The max merge count is set to 5 so overlap regions are divided into<a name="line.240"></a>
+<span class="sourceLineNo">241</span>      // two merge requests.<a name="line.241"></a>
+<span class="sourceLineNo">242</span>      TEST_UTIL.getHBaseCluster().getMaster().getConfiguration().setInt(<a name="line.242"></a>
+<span class="sourceLineNo">243</span>        "hbase.master.metafixer.max.merge.count", 5);<a name="line.243"></a>
+<span class="sourceLineNo">244</span><a name="line.244"></a>
+<span class="sourceLineNo">245</span>      // Get overlap regions<a name="line.245"></a>
+<span class="sourceLineNo">246</span>      HashSet&lt;String&gt; overlapRegions = new HashSet&lt;&gt;();<a name="line.246"></a>
+<span class="sourceLineNo">247</span>      for (Pair&lt;RegionInfo, RegionInfo&gt; pair : report.getOverlaps()) {<a name="line.247"></a>
+<span class="sourceLineNo">248</span>        overlapRegions.add(pair.getFirst().getRegionNameAsString());<a name="line.248"></a>
+<span class="sourceLineNo">249</span>        overlapRegions.add(pair.getSecond().getRegionNameAsString());<a name="line.249"></a>
+<span class="sourceLineNo">250</span>      }<a name="line.250"></a>
+<span class="sourceLineNo">251</span><a name="line.251"></a>
+<span class="sourceLineNo">252</span>      MetaFixer fixer = new MetaFixer(services);<a name="line.252"></a>
+<span class="sourceLineNo">253</span>      fixer.fixOverlaps(report);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>      AssignmentManager am = services.getAssignmentManager();<a name="line.254"></a>
+<span class="sourceLineNo">255</span><a name="line.255"></a>
+<span class="sourceLineNo">256</span>      await(200, () -&gt; {<a name="line.256"></a>
+<span class="sourceLineNo">257</span>        try {<a name="line.257"></a>
+<span class="sourceLineNo">258</span>          cj.scan();<a name="line.258"></a>
+<span class="sourceLineNo">259</span>          final CatalogJanitor.Report postReport = cj.getLastReport();<a name="line.259"></a>
+<span class="sourceLineNo">260</span>          RegionStates regionStates = am.getRegionStates();<a name="line.260"></a>
+<span class="sourceLineNo">261</span><a name="line.261"></a>
+<span class="sourceLineNo">262</span>          // Make sure that two merged regions are opened and GCs are done.<a name="line.262"></a>
+<span class="sourceLineNo">263</span>          if (postReport.getOverlaps().size() == 1) {<a name="line.263"></a>
+<span class="sourceLineNo">264</span>            Pair&lt;RegionInfo, RegionInfo&gt; pair = postReport.getOverlaps().get(0);<a name="line.264"></a>
+<span class="sourceLineNo">265</span>            if ((!overlapRegions.contains(pair.getFirst().getRegionNameAsString()) &amp;&amp;<a name="line.265"></a>
+<span class="sourceLineNo">266</span>              regionStates.getRegionState(pair.getFirst()).isOpened()) &amp;&amp;<a name="line.266"></a>
+<span class="sourceLineNo">267</span>              (!overlapRegions.contains(pair.getSecond().getRegionNameAsString()) &amp;&amp;<a name="line.267"></a>
+<span class="sourceLineNo">268</span>              regionStates.getRegionState(pair.getSecond()).isOpened())) {<a name="line.268"></a>
+<span class="sourceLineNo">269</span>              // Make sure GC is done.<a name="line.269"></a>
+<span class="sourceLineNo">270</span>              List&lt;RegionInfo&gt; firstParents = MetaTableAccessor.getMergeRegions(<a name="line.270"></a>
+<span class="sourceLineNo">271</span>                services.getConnection(), pair.getFirst().getRegionName());<a name="line.271"></a>
+<span class="sourceLineNo">272</span>              List&lt;RegionInfo&gt; secondParents = MetaTableAccessor.getMergeRegions(<a name="line.272"></a>
+<span class="sourceLineNo">273</span>                services.getConnection(), pair.getSecond().getRegionName());<a name="line.273"></a>
+<span class="sourceLineNo">274</span><a name="line.274"></a>
+<span class="sourceLineNo">275</span>              return (firstParents == null || firstParents.isEmpty()) &amp;&amp;<a name="line.275"></a>
+<span class="sourceLineNo">276</span>                (secondParents == null || secondParents.isEmpty());<a name="line.276"></a>
+<span class="sourceLineNo">277</span>            }<a name="line.277"></a>
+<span class="sourceLineNo">278</span>          }<a name="line.278"></a>
+<span class="sourceLineNo">279</span>          return false;<a name="line.279"></a>
+<span class="sourceLineNo">280</span>        } catch (Exception e) {<a name="line.280"></a>
+<span class="sourceLineNo">281</span>          throw new RuntimeException(e);<a name="line.281"></a>
+<span class="sourceLineNo">282</span>        }<a name="line.282"></a>
+<span class="sourceLineNo">283</span>      });<a name="line.283"></a>
+<span class="sourceLineNo">284</span><a name="line.284"></a>
+<span class="sourceLineNo">285</span>      // Second run of fixOverlap should fix all.<a name="line.285"></a>
+<span class="sourceLineNo">286</span>      report = cj.getLastReport();<a name="line.286"></a>
+<span class="sourceLineNo">287</span>      fixer.fixOverlaps(report);<a name="line.287"></a>
+<span class="sourceLineNo">288</span><a name="line.288"></a>
+<span class="sourceLineNo">289</span>      await(20, () -&gt; {<a name="line.289"></a>
+<span class="sourceLineNo">290</span>        try {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>          // Make sure it GC only once.<a name="line.291"></a>
+<span class="sourceLineNo">292</span>          return (cj.scan() &gt; 0);<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        } catch (Exception e) {<a name="line.293"></a>
+<span class="sourceLineNo">294</span>          throw new RuntimeException(e);<a name="line.294"></a>
+<span class="sourceLineNo">295</span>        }<a name="line.295"></a>
+<span class="sourceLineNo">296</span>      });<a name="line.296"></a>
+<span class="sourceLineNo">297</span><a name="line.297"></a>
+<span class="sourceLineNo">298</span>      // No holes reported.<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      cj.scan();<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      final CatalogJanitor.Report postReport = cj.getLastReport();<a name="line.300"></a>
+<span class="sourceLineNo">301</span>      assertTrue(postReport.isEmpty());<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    } finally {<a name="line.303"></a>
+<span class="sourceLineNo">304</span>      TEST_UTIL.getHBaseCluster().getMaster().getConfiguration().unset(<a name="line.304"></a>
+<span class="sourceLineNo">305</span>        "hbase.master.metafixer.max.merge.count");<a name="line.305"></a>
+<span class="sourceLineNo">306</span><a name="line.306"></a>
+<span class="sourceLineNo">307</span>      TEST_UTIL.deleteTable(tn);<a name="line.307"></a>
+<span class="sourceLineNo">308</span>    }<a name="line.308"></a>
+<span class="sourceLineNo">309</span>  }<a name="line.309"></a>
+<span class="sourceLineNo">310</span><a name="line.310"></a>
+<span class="sourceLineNo">311</span>  /**<a name="line.311"></a>
+<span class="sourceLineNo">312</span>   * Make it so a big overlap spans many Regions, some of which are non-contiguous. Make it so<a name="line.312"></a>
+<span class="sourceLineNo">313</span>   * we can fix this condition. HBASE-24247<a name="line.313"></a>
+<span class="sourceLineNo">314</span>   */<a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Test<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public void testOverlapWithMergeOfNonContiguous() throws Exception {<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    TableName tn = TableName.valueOf(this.name.getMethodName());<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    TEST_UTIL.createMultiRegionTable(tn, HConstants.CATALOG_FAMILY);<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    List&lt;RegionInfo&gt; ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>    assertTrue(ris.size() &gt; 5);<a name="line.320"></a>
+<span class="sourceLineNo">321</span>    MasterServices services = TEST_UTIL.getHBaseCluster().getMaster();<a name="line.321"></a>
+<span class="sourceLineNo">322</span>    services.getCatalogJanitor().scan();<a name="line.322"></a>
+<span class="sourceLineNo">323</span>    CatalogJanitor.Report report = services.getCatalogJanitor().getLastReport();<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    assertTrue(report.isEmpty());<a name="line.324"></a>
+<span class="sourceLineNo">325</span>    // Make a simple overlap spanning second and third region.<a name="line.325"></a>
+<span class="sourceLineNo">326</span>    makeOverlap(services, ris.get(1), ris.get(5));<a name="line.326"></a>
+<span class="sourceLineNo">327</span>    // Now Delete a region under the overlap to manufacture non-contiguous sub regions.<a name="line.327"></a>
+<span class="sourceLineNo">328</span>    RegionInfo deletedRegion = ris.get(3);<a name="line.328"></a>
+<span class="sourceLineNo">329</span>    long pid = services.getAssignmentManager().unassign(deletedRegion);<a name="line.329"></a>
+<span class="sourceLineNo">330</span>    while (!services.getMasterProcedureExecutor().isFinished(pid)) {<a name="line.330"></a>
+<span class="sourceLineNo">331</span>      Threads.sleep(100);<a name="line.331"></a>
+<span class="sourceLineNo">332</span>    }<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    GCRegionProcedure procedure =<a name="line.333"></a>
+<span class="sourceLineNo">334</span>      new GCRegionProcedure(services.getMasterProcedureExecutor().getEnvironment(), ris.get(3));<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    pid = services.getMasterProcedureExecutor().submitProcedure(procedure);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    while (!services.getMasterProcedureExecutor().isFinished(pid)) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      Threads.sleep(100);<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span>    Threads.sleep(10000);<a name="line.339"></a>
+<span class="sourceLineNo">340</span>    services.getCatalogJanitor().scan();<a name="line.340"></a>
+<span class="sourceLineNo">341</span>    report = services.getCatalogJanitor().getLastReport();<a name="line.341"></a>
+<span class="sourceLineNo">342</span>    assertEquals(1, MetaFixer.calculateMerges(10, report.getOverlaps()).size());<a name="line.342"></a>
+<span class="sourceLineNo">343</span>    MetaFixer fixer = new MetaFixer(services);<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    fixer.fixOverlaps(report);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    await(10, () -&gt; {<a name="line.345"></a>
+<span class="sourceLineNo">346</span>      try {<a name="line.346"></a>
+<span class="sourceLineNo">347</span>        services.getCatalogJanitor().scan();<a name="line.347"></a>
+<span class="sourceLineNo">348</span>        final CatalogJanitor.Report postReport = services.getCatalogJanitor().getLastReport();<a name="line.348"></a>
+<span class="sourceLineNo">349</span>        return postReport.isEmpty();<a name="line.349"></a>
+<span class="sourceLineNo">350</span>      } catch (Exception e) {<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        throw new RuntimeException(e);<a name="line.351"></a>
+<span class="sourceLineNo">352</span>      }<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    });<a name="line.353"></a>
+<span class="sourceLineNo">354</span>  }<a name="line.354"></a>
+<span class="sourceLineNo">355</span><a name="line.355"></a>
+<span class="sourceLineNo">356</span>  /**<a name="line.356"></a>
+<span class="sourceLineNo">357</span>   * Await the successful return of {@code condition}, sleeping {@code sleepMillis} between<a name="line.357"></a>
+<span class="sourceLineNo">358</span>   * invocations.<a name="line.358"></a>
+<span class="sourceLineNo">359</span>   */<a name="line.359"></a>
+<span class="sourceLineNo">360</span>  private static void await(final long sleepMillis, final BooleanSupplier condition)<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    throws InterruptedException {<a name="line.361"></a>
+<span class="sourceLineNo">362</span>    try {<a name="line.362"></a>
+<span class="sourceLineNo">363</span>      while (!condition.getAsBoolean()) {<a name="line.363"></a>
+<span class="sourceLineNo">364</span>        Thread.sleep(sleepMillis);<a name="line.364"></a>
+<span class="sourceLineNo">365</span>      }<a name="line.365"></a>
+<span class="sourceLineNo">366</span>    } catch (RuntimeException e) {<a name="line.366"></a>
+<span class="sourceLineNo">367</span>      if (e.getCause() instanceof AssertionError) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>        throw (AssertionError) e.getCause();<a name="line.368"></a>
+<span class="sourceLineNo">369</span>      }<a name="line.369"></a>
+<span class="sourceLineNo">370</span>      throw e;<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>