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/04/26 14:45:03 UTC

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

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 4b4f57b  Published site at ec0d9d767e697c8d6726d15bf06ce9a19a756263.
4b4f57b is described below

commit 4b4f57bb659f5793dd9735aa4191aae373cd397d
Author: jenkins <bu...@apache.org>
AuthorDate: Sun Apr 26 14:44:51 2020 +0000

    Published site at ec0d9d767e697c8d6726d15bf06ce9a19a756263.
---
 acid-semantics.html                                |   2 +-
 apache_hbase_reference_guide.pdf                   |   4 +-
 book.html                                          |   2 +-
 bulk-loads.html                                    |   2 +-
 checkstyle-aggregate.html                          |  76 +--
 checkstyle.rss                                     |   4 +-
 coc.html                                           |   2 +-
 dependencies.html                                  |   2 +-
 dependency-convergence.html                        |   2 +-
 dependency-info.html                               |   2 +-
 dependency-management.html                         |   2 +-
 devapidocs/constant-values.html                    |   4 +-
 devapidocs/index-all.html                          |   4 +-
 .../bucket/BucketAllocator.IndexStatistics.html    |  30 +-
 .../hbase/io/hfile/bucket/BucketAllocator.html     |  56 +-
 .../hbase/security/AbstractHBaseSaslRpcClient.html |  27 +-
 .../security/NettyHBaseSaslRpcClientHandler.html   |   6 +-
 .../src-html/org/apache/hadoop/hbase/Version.html  |   4 +-
 .../io/hfile/bucket/BucketAllocator.Bucket.html    | 705 +++++++++++----------
 .../bucket/BucketAllocator.BucketSizeInfo.html     | 705 +++++++++++----------
 .../bucket/BucketAllocator.IndexStatistics.html    | 705 +++++++++++----------
 .../hbase/io/hfile/bucket/BucketAllocator.html     | 705 +++++++++++----------
 .../hbase/security/AbstractHBaseSaslRpcClient.html |  58 +-
 .../security/NettyHBaseSaslRpcClientHandler.html   | 128 ++--
 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 +-
 44 files changed, 1622 insertions(+), 1655 deletions(-)

diff --git a/acid-semantics.html b/acid-semantics.html
index 83e143a..321cac7 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 ceca3eb..187aa65 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:20200425192308+00'00')
-/CreationDate (D:20200425193428+00'00')
+/ModDate (D:20200426143116+00'00')
+/CreationDate (D:20200426144210+00'00')
 >>
 endobj
 2 0 obj
diff --git a/book.html b/book.html
index 5ed8146..6b11adc 100644
--- a/book.html
+++ b/book.html
@@ -45211,7 +45211,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-04-25 19:23:08 UTC
+Last updated 2020-04-26 14:31:16 UTC
 </div>
 </div>
 <script type="text/x-mathjax-config">
diff --git a/bulk-loads.html b/bulk-loads.html
index 9c1e6d8..4250226 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 edc2d72..739112f 100644
--- a/checkstyle-aggregate.html
+++ b/checkstyle-aggregate.html
@@ -169,7 +169,7 @@
 <td>4232</td>
 <td>0</td>
 <td>0</td>
-<td>9911</td></tr></table></div>
+<td>9907</td></tr></table></div>
 <div class="section">
 <h2><a name="Files"></a>Files</h2>
 <table border="0" class="table table-striped">
@@ -6112,7 +6112,7 @@
 <td><a href="#org.apache.hadoop.hbase.security.NettyHBaseSaslRpcClientHandler.java">org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.java</a></td>
 <td>0</td>
 <td>0</td>
-<td>6</td></tr>
+<td>2</td></tr>
 <tr class="a">
 <td><a href="#org.apache.hadoop.hbase.security.SaslChallengeDecoder.java">org/apache/hadoop/hbase/security/SaslChallengeDecoder.java</a></td>
 <td>0</td>
@@ -7463,12 +7463,12 @@
 <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>595</td>
+<td>596</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
 <tr class="a">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_javadoc.html#NonEmptyAtclauseDescription">NonEmptyAtclauseDescription</a></td>
-<td>2529</td>
+<td>2528</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
 <tr class="b">
 <td>misc</td>
@@ -7491,7 +7491,7 @@
 <ul>
 <li>max: <tt>&quot;100&quot;</tt></li>
 <li>ignorePattern: <tt>&quot;^package.*|^import.*|a href|href|http://|https://|ftp://|org.apache.thrift.|com.google.protobuf.|hbase.protobuf.generated&quot;</tt></li></ul></td>
-<td>954</td>
+<td>950</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
 <tr class="b">
 <td></td>
@@ -8496,7 +8496,7 @@
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
-<td>NonEmptyAtclauseDescription</td>
+<td>JavadocTagContinuationIndentation</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">
@@ -32774,109 +32774,109 @@
 <td>misc</td>
 <td>ArrayTypeStyle</td>
 <td>Array brackets at illegal position.</td>
-<td>274</td></tr>
+<td>275</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 6, expected level should be one of the following: 4, 54.</td>
-<td>275</td></tr>
+<td>276</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 6, expected level should be one of the following: 4, 54.</td>
-<td>276</td></tr>
+<td>277</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 6, expected level should be one of the following: 4, 54.</td>
-<td>277</td></tr>
+<td>278</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 6, expected level should be one of the following: 4, 54.</td>
-<td>278</td></tr>
+<td>279</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'for' construct must use '{}'s.</td>
-<td>285</td></tr>
+<td>286</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>286</td></tr>
+<td>287</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>312</td></tr>
+<td>313</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>339</td></tr>
+<td>340</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>414</td></tr>
+<td>415</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>436</td></tr>
+<td>437</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>437</td></tr>
+<td>438</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>452</td></tr>
+<td>453</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>461</td></tr>
+<td>462</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'for' construct must use '{}'s.</td>
-<td>570</td></tr>
+<td>571</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>misc</td>
 <td>ArrayTypeStyle</td>
 <td>Array brackets at illegal position.</td>
-<td>575</td></tr>
+<td>576</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'for' construct must use '{}'s.</td>
-<td>577</td></tr>
+<td>578</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>whitespace</td>
 <td>ParenPad</td>
 <td>')' is preceded with whitespace.</td>
-<td>610</td></tr></table></div>
+<td>611</td></tr></table></div>
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.io.hfile.bucket.BucketCache.java">org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java</h3>
 <table border="0" class="table table-striped">
@@ -65885,31 +65885,7 @@
 <td>imports</td>
 <td>ImportOrder</td>
 <td>Wrong order for 'org.apache.hadoop.hbase.ipc.FallbackDisallowedException' import.</td>
-<td>34</td></tr>
-<tr class="a">
-<td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
-<td>sizes</td>
-<td>LineLength</td>
-<td>Line is longer than 100 characters (found 116).</td>
-<td>133</td></tr>
-<tr class="b">
-<td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
-<td>sizes</td>
-<td>LineLength</td>
-<td>Line is longer than 100 characters (found 119).</td>
-<td>134</td></tr>
-<tr class="a">
-<td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
-<td>sizes</td>
-<td>LineLength</td>
-<td>Line is longer than 100 characters (found 116).</td>
-<td>135</td></tr>
-<tr class="b">
-<td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
-<td>sizes</td>
-<td>LineLength</td>
-<td>Line is longer than 100 characters (found 111).</td>
-<td>136</td></tr></table></div>
+<td>34</td></tr></table></div>
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.security.SaslChallengeDecoder.java">org/apache/hadoop/hbase/security/SaslChallengeDecoder.java</h3>
 <table border="0" class="table table-striped">
@@ -79904,7 +79880,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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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.rss b/checkstyle.rss
index d15ef75..a98f55b 100644
--- a/checkstyle.rss
+++ b/checkstyle.rss
@@ -26,7 +26,7 @@ under the License.
     <copyright>&#169;2007 - 2020 The Apache Software Foundation</copyright>
     <item>
       <title>File: 4232,
-             Errors: 9911,
+             Errors: 9907,
              Warnings: 0,
              Infos: 0
       </title>
@@ -54207,7 +54207,7 @@ under the License.
                   0
                 </td>
                 <td>
-                  6
+                  2
                 </td>
               </tr>
                           <tr>
diff --git a/coc.html b/coc.html
index d3fdb7d..86ffd96 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 7a73261..3eabebe 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 6bded75..c2c0878 100644
--- a/dependency-convergence.html
+++ b/dependency-convergence.html
@@ -757,7 +757,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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 23a9523..d925fd5 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 9682bb9..6230bc0 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 cc81d52..480f249 100644
--- a/devapidocs/constant-values.html
+++ b/devapidocs/constant-values.html
@@ -4165,14 +4165,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>"Sat Apr 25 19:30:56 UTC 2020"</code></td>
+<td class="colLast"><code>"Sun Apr 26 14:38:40 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>"e6cc5eb2f0623f02eaa3542308fc3d82fd3abd9f"</code></td>
+<td class="colLast"><code>"ec0d9d767e697c8d6726d15bf06ce9a19a756263"</code></td>
 </tr>
 <tr class="altColor">
 <td class="colFirst"><a name="org.apache.hadoop.hbase.Version.srcChecksum">
diff --git a/devapidocs/index-all.html b/devapidocs/index-all.html
index 122621a..716a790 100644
--- a/devapidocs/index-all.html
+++ b/devapidocs/index-all.html
@@ -42518,8 +42518,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html#getInitialResponse--">getInitialResponse()</a></span> - Method in class org.apache.hadoop.hbase.security.<a href="org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html" title="class in org.apache.hadoop.hbase.security">AbstractHBaseSaslRpcClient</a></dt>
 <dd>
-<div class="block">Computes the initial response a client sends to a server to begin the SASL
- challenge/response handshake.</div>
+<div class="block">Computes the initial response a client sends to a server to begin the SASL challenge/response
+ handshake.</div>
 </dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/GCMergedRegionsProcedure.html#getInitialState--">getInitialState()</a></span> - Method in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/GCMergedRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">GCMergedRegionsProcedure</a></dt>
 <dd>
diff --git a/devapidocs/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html b/devapidocs/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html
index ae6cd95..e715db2 100644
--- a/devapidocs/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html
+++ b/devapidocs/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html
@@ -113,7 +113,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.494">BucketAllocator.IndexStatistics</a>
+<pre>static class <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.495">BucketAllocator.IndexStatistics</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>
@@ -248,7 +248,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>freeCount</h4>
-<pre>private&nbsp;long <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.495">freeCount</a></pre>
+<pre>private&nbsp;long <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.496">freeCount</a></pre>
 </li>
 </ul>
 <a name="usedCount">
@@ -257,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>usedCount</h4>
-<pre>private&nbsp;long <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.495">usedCount</a></pre>
+<pre>private&nbsp;long <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.496">usedCount</a></pre>
 </li>
 </ul>
 <a name="itemSize">
@@ -266,7 +266,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>itemSize</h4>
-<pre>private&nbsp;long <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.495">itemSize</a></pre>
+<pre>private&nbsp;long <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.496">itemSize</a></pre>
 </li>
 </ul>
 <a name="totalCount">
@@ -275,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>totalCount</h4>
-<pre>private&nbsp;long <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.495">totalCount</a></pre>
+<pre>private&nbsp;long <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.496">totalCount</a></pre>
 </li>
 </ul>
 </li>
@@ -292,7 +292,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>IndexStatistics</h4>
-<pre>public&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.525">IndexStatistics</a>(long&nbsp;free,
+<pre>public&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.526">IndexStatistics</a>(long&nbsp;free,
                        long&nbsp;used,
                        long&nbsp;itemSize)</pre>
 </li>
@@ -303,7 +303,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>IndexStatistics</h4>
-<pre>public&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.529">IndexStatistics</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.530">IndexStatistics</a>()</pre>
 </li>
 </ul>
 </li>
@@ -320,7 +320,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>freeCount</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.497">freeCount</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.498">freeCount</a>()</pre>
 </li>
 </ul>
 <a name="usedCount--">
@@ -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>usedCount</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.501">usedCount</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.502">usedCount</a>()</pre>
 </li>
 </ul>
 <a name="totalCount--">
@@ -338,7 +338,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>totalCount</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.505">totalCount</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.506">totalCount</a>()</pre>
 </li>
 </ul>
 <a name="freeBytes--">
@@ -347,7 +347,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>freeBytes</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.509">freeBytes</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.510">freeBytes</a>()</pre>
 </li>
 </ul>
 <a name="usedBytes--">
@@ -356,7 +356,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>usedBytes</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.513">usedBytes</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.514">usedBytes</a>()</pre>
 </li>
 </ul>
 <a name="totalBytes--">
@@ -365,7 +365,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>totalBytes</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.517">totalBytes</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.518">totalBytes</a>()</pre>
 </li>
 </ul>
 <a name="itemSize--">
@@ -374,7 +374,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>itemSize</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.521">itemSize</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.522">itemSize</a>()</pre>
 </li>
 </ul>
 <a name="setTo-long-long-long-">
@@ -383,7 +383,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>setTo</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.533">setTo</a>(long&nbsp;free,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html#line.534">setTo</a>(long&nbsp;free,
                   long&nbsp;used,
                   long&nbsp;itemSize)</pre>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html b/devapidocs/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html
index 1e1efd2..4f030f2 100644
--- a/devapidocs/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html
+++ b/devapidocs/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html
@@ -363,7 +363,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_BUCKET_SIZES</h4>
-<pre>private static final&nbsp;int[] <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.274">DEFAULT_BUCKET_SIZES</a></pre>
+<pre>private static final&nbsp;int[] <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.275">DEFAULT_BUCKET_SIZES</a></pre>
 </li>
 </ul>
 <a name="FEWEST_ITEMS_IN_BUCKET">
@@ -372,7 +372,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>FEWEST_ITEMS_IN_BUCKET</h4>
-<pre>public static final&nbsp;int <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.294">FEWEST_ITEMS_IN_BUCKET</a></pre>
+<pre>public static final&nbsp;int <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.295">FEWEST_ITEMS_IN_BUCKET</a></pre>
 <div class="block">So, what is the minimum amount of items we'll tolerate in a single bucket?</div>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
@@ -386,7 +386,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>bucketSizes</h4>
-<pre>private final&nbsp;int[] <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.296">bucketSizes</a></pre>
+<pre>private final&nbsp;int[] <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.297">bucketSizes</a></pre>
 </li>
 </ul>
 <a name="bigItemSize">
@@ -395,7 +395,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>bigItemSize</h4>
-<pre>private final&nbsp;int <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.297">bigItemSize</a></pre>
+<pre>private final&nbsp;int <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.298">bigItemSize</a></pre>
 </li>
 </ul>
 <a name="bucketCapacity">
@@ -404,7 +404,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>bucketCapacity</h4>
-<pre>private final&nbsp;long <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.299">bucketCapacity</a></pre>
+<pre>private final&nbsp;long <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.300">bucketCapacity</a></pre>
 </li>
 </ul>
 <a name="buckets">
@@ -413,7 +413,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>buckets</h4>
-<pre>private&nbsp;<a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.Bucket.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocator.Bucket</a>[] <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.300">buckets</a></pre>
+<pre>private&nbsp;<a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.Bucket.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocator.Bucket</a>[] <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.301">buckets</a></pre>
 </li>
 </ul>
 <a name="bucketSizeInfos">
@@ -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>bucketSizeInfos</h4>
-<pre>private&nbsp;<a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.BucketSizeInfo.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocator.BucketSizeInfo</a>[] <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.301">bucketSizeInfos</a></pre>
+<pre>private&nbsp;<a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.BucketSizeInfo.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocator.BucketSizeInfo</a>[] <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.302">bucketSizeInfos</a></pre>
 </li>
 </ul>
 <a name="totalSize">
@@ -431,7 +431,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>totalSize</h4>
-<pre>private final&nbsp;long <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.302">totalSize</a></pre>
+<pre>private final&nbsp;long <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.303">totalSize</a></pre>
 </li>
 </ul>
 <a name="usedSize">
@@ -440,7 +440,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>usedSize</h4>
-<pre>private transient&nbsp;long <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.303">usedSize</a></pre>
+<pre>private transient&nbsp;long <a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.304">usedSize</a></pre>
 </li>
 </ul>
 </li>
@@ -457,7 +457,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>BucketAllocator</h4>
-<pre><a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.305">BucketAllocator</a>(long&nbsp;availableSpace,
+<pre><a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.306">BucketAllocator</a>(long&nbsp;availableSpace,
                 int[]&nbsp;bucketSizes)
          throws <a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocatorException.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocatorException</a></pre>
 <dl>
@@ -472,7 +472,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>BucketAllocator</h4>
-<pre><a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.341">BucketAllocator</a>(long&nbsp;availableSpace,
+<pre><a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.342">BucketAllocator</a>(long&nbsp;availableSpace,
                 int[]&nbsp;bucketSizes,
                 <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/BlockCacheKey.html" title="class in org.apache.hadoop.hbase.io.hfile">BlockCacheKey</a>,<a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketEntry.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketEntry</a>&gt;&nbsp;map,
                 <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/LongAdder.html?is-external=true" title="class or interface in java.util.concurrent.atomic">LongAdder</a>&nbsp;realCacheSize)
@@ -503,7 +503,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>roundUpToBucketSizeInfo</h4>
-<pre>public&nbsp;<a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.BucketSizeInfo.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocator.BucketSizeInfo</a>&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.284">roundUpToBucketSizeInfo</a>(int&nbsp;blockSize)</pre>
+<pre>public&nbsp;<a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.BucketSizeInfo.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocator.BucketSizeInfo</a>&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.285">roundUpToBucketSizeInfo</a>(int&nbsp;blockSize)</pre>
 <div class="block">Round up the given block size to bucket size, and get the corresponding
  BucketSizeInfo</div>
 </li>
@@ -514,7 +514,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>toString</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.410">toString</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.411">toString</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true#toString--" title="class or interface in java.lang">toString</a></code>&nbsp;in class&nbsp;<code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></code></dd>
@@ -527,7 +527,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getUsedSize</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.421">getUsedSize</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.422">getUsedSize</a>()</pre>
 </li>
 </ul>
 <a name="getFreeSize--">
@@ -536,7 +536,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getFreeSize</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.425">getFreeSize</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.426">getFreeSize</a>()</pre>
 </li>
 </ul>
 <a name="getTotalSize--">
@@ -545,7 +545,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getTotalSize</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.429">getTotalSize</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.430">getTotalSize</a>()</pre>
 </li>
 </ul>
 <a name="allocateBlock-int-">
@@ -554,7 +554,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>allocateBlock</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.440">allocateBlock</a>(int&nbsp;blockSize)
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.441">allocateBlock</a>(int&nbsp;blockSize)
                    throws <a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/CacheFullException.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">CacheFullException</a>,
                           <a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocatorException.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocatorException</a></pre>
 <div class="block">Allocate a block with specified size. Return the offset</div>
@@ -575,7 +575,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>grabGlobalCompletelyFreeBucket</h4>
-<pre>private&nbsp;<a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.Bucket.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocator.Bucket</a>&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.458">grabGlobalCompletelyFreeBucket</a>()</pre>
+<pre>private&nbsp;<a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.Bucket.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocator.Bucket</a>&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.459">grabGlobalCompletelyFreeBucket</a>()</pre>
 </li>
 </ul>
 <a name="freeBlock-long-">
@@ -584,7 +584,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>freeBlock</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.471">freeBlock</a>(long&nbsp;offset)</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.472">freeBlock</a>(long&nbsp;offset)</pre>
 <div class="block">Free a block with the offset</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -600,7 +600,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>sizeIndexOfAllocation</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.480">sizeIndexOfAllocation</a>(long&nbsp;offset)</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.481">sizeIndexOfAllocation</a>(long&nbsp;offset)</pre>
 </li>
 </ul>
 <a name="sizeOfAllocation-long-">
@@ -609,7 +609,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>sizeOfAllocation</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.487">sizeOfAllocation</a>(long&nbsp;offset)</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.488">sizeOfAllocation</a>(long&nbsp;offset)</pre>
 </li>
 </ul>
 <a name="getBuckets--">
@@ -618,7 +618,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getBuckets</h4>
-<pre>public&nbsp;<a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.Bucket.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocator.Bucket</a>[]&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.541">getBuckets</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.Bucket.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocator.Bucket</a>[]&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.542">getBuckets</a>()</pre>
 </li>
 </ul>
 <a name="logStatistics--">
@@ -627,7 +627,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>logStatistics</h4>
-<pre>void&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.545">logStatistics</a>()</pre>
+<pre>void&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.546">logStatistics</a>()</pre>
 </li>
 </ul>
 <a name="getIndexStatistics-org.apache.hadoop.hbase.io.hfile.bucket.BucketAllocator.IndexStatistics-">
@@ -636,7 +636,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getIndexStatistics</h4>
-<pre><a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocator.IndexStatistics</a>[]&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.557">getIndexStatistics</a>(<a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html" title="class in org.apache.hadoop.hbas [...]
+<pre><a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocator.IndexStatistics</a>[]&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.558">getIndexStatistics</a>(<a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html" title="class in org.apache.hadoop.hbas [...]
 </li>
 </ul>
 <a name="getIndexStatistics--">
@@ -645,7 +645,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getIndexStatistics</h4>
-<pre><a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocator.IndexStatistics</a>[]&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.568">getIndexStatistics</a>()</pre>
+<pre><a href="../../../../../../../org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketAllocator.IndexStatistics</a>[]&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.569">getIndexStatistics</a>()</pre>
 </li>
 </ul>
 <a name="freeBlock-long:A-">
@@ -654,7 +654,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>freeBlock</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.575">freeBlock</a>(long[]&nbsp;freeList)</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.576">freeBlock</a>(long[]&nbsp;freeList)</pre>
 </li>
 </ul>
 <a name="getBucketIndex-long-">
@@ -663,7 +663,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getBucketIndex</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.582">getBucketIndex</a>(long&nbsp;offset)</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.583">getBucketIndex</a>(long&nbsp;offset)</pre>
 </li>
 </ul>
 <a name="getLeastFilledBuckets-java.util.Set-int-">
@@ -672,7 +672,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getLeastFilledBuckets</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt;&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.597">getLeastFilledBuckets</a>(<a href="https://docs.oracle.com/javase/8/docs/ [...]
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt;&nbsp;<a href="../../../../../../../src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html#line.598">getLeastFilledBuckets</a>(<a href="https://docs.oracle.com/javase/8/docs/ [...]
                                           int&nbsp;bucketCount)</pre>
 <div class="block">Returns a set of indices of the buckets that are least filled
  excluding the offsets, we also the fully free buckets for the
diff --git a/devapidocs/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html b/devapidocs/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html
index bfacda2..8baf3dc 100644
--- a/devapidocs/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html
+++ b/devapidocs/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html
@@ -222,8 +222,8 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <tr id="i2" class="altColor">
 <td class="colFirst"><code>byte[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html#getInitialResponse--">getInitialResponse</a></span>()</code>
-<div class="block">Computes the initial response a client sends to a server to begin the SASL
- challenge/response handshake.</div>
+<div class="block">Computes the initial response a client sends to a server to begin the SASL challenge/response
+ handshake.</div>
 </td>
 </tr>
 <tr id="i3" class="rowColor">
@@ -366,20 +366,15 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getInitialResponse</h4>
-<pre>public&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html#line.104">getInitialResponse</a>()
+<pre>public&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html#line.98">getInitialResponse</a>()
                           throws <a href="https://docs.oracle.com/javase/8/docs/api/javax/security/sasl/SaslException.html?is-external=true" title="class or interface in javax.security.sasl">SaslException</a></pre>
-<div class="block">Computes the initial response a client sends to a server to begin the SASL
- challenge/response handshake. If the client's SASL mechanism does not require
- that an initial response is sent to begin the handshake, this method will return
- a null byte array, indicating no initial response needs to be sent by this client.
-
- It is unclear as to whether all SASL implementations will return a non-empty initial
- response, so this implementation is written such that this is allowed. All known
- SASL mechanism implementations in the JDK provide non-empty initial responses.</div>
+<div class="block">Computes the initial response a client sends to a server to begin the SASL challenge/response
+ handshake. If the client's SASL mechanism does not have an initial response, an empty token
+ will be returned without querying the evaluateChallenge method, as an authentication processing
+ must be started by client.</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
-<dd>The client's initial response to send the server (which may be empty), or null
-    if this implementation does not require an initial response to be sent.</dd>
+<dd>The client's initial response to send the server (which may be empty).</dd>
 <dt><span class="throwsLabel">Throws:</span></dt>
 <dd><code><a href="https://docs.oracle.com/javase/8/docs/api/javax/security/sasl/SaslException.html?is-external=true" title="class or interface in javax.security.sasl">SaslException</a></code></dd>
 </dl>
@@ -391,7 +386,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isComplete</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html#line.111">isComplete</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html#line.105">isComplete</a>()</pre>
 </li>
 </ul>
 <a name="evaluateChallenge-byte:A-">
@@ -400,7 +395,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>evaluateChallenge</h4>
-<pre>public&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html#line.115">evaluateChallenge</a>(byte[]&nbsp;challenge)
+<pre>public&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html#line.109">evaluateChallenge</a>(byte[]&nbsp;challenge)
                          throws <a href="https://docs.oracle.com/javase/8/docs/api/javax/security/sasl/SaslException.html?is-external=true" title="class or interface in javax.security.sasl">SaslException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -414,7 +409,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>dispose</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html#line.120">dispose</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html#line.114">dispose</a>()</pre>
 <div class="block">Release resources used by wrapped saslClient</div>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.html b/devapidocs/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.html
index 9678d3a..55f4bf2 100644
--- a/devapidocs/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.html
+++ b/devapidocs/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.html
@@ -482,7 +482,7 @@ extends org.apache.hbase.thirdparty.io.netty.channel.SimpleChannelInboundHandler
 <ul class="blockList">
 <li class="blockList">
 <h4>channelRead0</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.html#line.145">channelRead0</a>(org.apache.hbase.thirdparty.io.netty.channel.ChannelHandlerContext&nbsp;ctx,
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.html#line.143">channelRead0</a>(org.apache.hbase.thirdparty.io.netty.channel.ChannelHandlerContext&nbsp;ctx,
                             org.apache.hbase.thirdparty.io.netty.buffer.ByteBuf&nbsp;msg)
                      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>
@@ -499,7 +499,7 @@ extends org.apache.hbase.thirdparty.io.netty.channel.SimpleChannelInboundHandler
 <ul class="blockList">
 <li class="blockList">
 <h4>channelInactive</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.html#line.175">channelInactive</a>(org.apache.hbase.thirdparty.io.netty.channel.ChannelHandlerContext&nbsp;ctx)
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.html#line.173">channelInactive</a>(org.apache.hbase.thirdparty.io.netty.channel.ChannelHandlerContext&nbsp;ctx)
                      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="overrideSpecifyLabel">Specified by:</span></dt>
@@ -517,7 +517,7 @@ extends org.apache.hbase.thirdparty.io.netty.channel.SimpleChannelInboundHandler
 <ul class="blockListLast">
 <li class="blockList">
 <h4>exceptionCaught</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.html#line.182">exceptionCaught</a>(org.apache.hbase.thirdparty.io.netty.channel.ChannelHandlerContext&nbsp;ctx,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.html#line.180">exceptionCaught</a>(org.apache.hbase.thirdparty.io.netty.channel.ChannelHandlerContext&nbsp;ctx,
                             <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang">Throwable</a>&nbsp;cause)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</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 3716a84..84b90bb 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 = "e6cc5eb2f0623f02eaa3542308fc3d82fd3abd9f";<a name="line.13"></a>
+<span class="sourceLineNo">013</span>  public static final String revision = "ec0d9d767e697c8d6726d15bf06ce9a19a756263";<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 = "Sat Apr 25 19:30:56 UTC 2020";<a name="line.15"></a>
+<span class="sourceLineNo">015</span>  public static final String date = "Sun Apr 26 14:38:40 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/io/hfile/bucket/BucketAllocator.Bucket.html b/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.Bucket.html
index a3cd853..0a4475b 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.Bucket.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.Bucket.html
@@ -277,358 +277,359 @@
 <span class="sourceLineNo">269</span><a name="line.269"></a>
 <span class="sourceLineNo">270</span>  // Default block size in hbase is 64K, so we choose more sizes near 64K, you'd better<a name="line.270"></a>
 <span class="sourceLineNo">271</span>  // reset it according to your cluster's block size distribution<a name="line.271"></a>
-<span class="sourceLineNo">272</span>  // TODO Support the view of block size distribution statistics<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  // TODO: Why we add the extra 1024 bytes? Slop?<a name="line.273"></a>
-<span class="sourceLineNo">274</span>  private static final int DEFAULT_BUCKET_SIZES[] = { 4 * 1024 + 1024, 8 * 1024 + 1024,<a name="line.274"></a>
-<span class="sourceLineNo">275</span>      16 * 1024 + 1024, 32 * 1024 + 1024, 40 * 1024 + 1024, 48 * 1024 + 1024,<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      56 * 1024 + 1024, 64 * 1024 + 1024, 96 * 1024 + 1024, 128 * 1024 + 1024,<a name="line.276"></a>
-<span class="sourceLineNo">277</span>      192 * 1024 + 1024, 256 * 1024 + 1024, 384 * 1024 + 1024,<a name="line.277"></a>
-<span class="sourceLineNo">278</span>      512 * 1024 + 1024 };<a name="line.278"></a>
-<span class="sourceLineNo">279</span><a name="line.279"></a>
-<span class="sourceLineNo">280</span>  /**<a name="line.280"></a>
-<span class="sourceLineNo">281</span>   * Round up the given block size to bucket size, and get the corresponding<a name="line.281"></a>
-<span class="sourceLineNo">282</span>   * BucketSizeInfo<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   */<a name="line.283"></a>
-<span class="sourceLineNo">284</span>  public BucketSizeInfo roundUpToBucketSizeInfo(int blockSize) {<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    for (int i = 0; i &lt; bucketSizes.length; ++i)<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      if (blockSize &lt;= bucketSizes[i])<a name="line.286"></a>
-<span class="sourceLineNo">287</span>        return bucketSizeInfos[i];<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    return null;<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>   * So, what is the minimum amount of items we'll tolerate in a single bucket?<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   */<a name="line.293"></a>
-<span class="sourceLineNo">294</span>  static public final int FEWEST_ITEMS_IN_BUCKET = 4;<a name="line.294"></a>
-<span class="sourceLineNo">295</span><a name="line.295"></a>
-<span class="sourceLineNo">296</span>  private final int[] bucketSizes;<a name="line.296"></a>
-<span class="sourceLineNo">297</span>  private final int bigItemSize;<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  // The capacity size for each bucket<a name="line.298"></a>
-<span class="sourceLineNo">299</span>  private final long bucketCapacity;<a name="line.299"></a>
-<span class="sourceLineNo">300</span>  private Bucket[] buckets;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>  private BucketSizeInfo[] bucketSizeInfos;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>  private final long totalSize;<a name="line.302"></a>
-<span class="sourceLineNo">303</span>  private transient long usedSize = 0;<a name="line.303"></a>
-<span class="sourceLineNo">304</span><a name="line.304"></a>
-<span class="sourceLineNo">305</span>  BucketAllocator(long availableSpace, int[] bucketSizes)<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      throws BucketAllocatorException {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>    this.bucketSizes = bucketSizes == null ? DEFAULT_BUCKET_SIZES : bucketSizes;<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    Arrays.sort(this.bucketSizes);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>    this.bigItemSize = Ints.max(this.bucketSizes);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>    this.bucketCapacity = FEWEST_ITEMS_IN_BUCKET * (long) bigItemSize;<a name="line.310"></a>
-<span class="sourceLineNo">311</span>    buckets = new Bucket[(int) (availableSpace / bucketCapacity)];<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    if (buckets.length &lt; this.bucketSizes.length)<a name="line.312"></a>
-<span class="sourceLineNo">313</span>      throw new BucketAllocatorException("Bucket allocator size too small (" + buckets.length +<a name="line.313"></a>
-<span class="sourceLineNo">314</span>        "); must have room for at least " + this.bucketSizes.length + " buckets");<a name="line.314"></a>
-<span class="sourceLineNo">315</span>    bucketSizeInfos = new BucketSizeInfo[this.bucketSizes.length];<a name="line.315"></a>
-<span class="sourceLineNo">316</span>    for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      bucketSizeInfos[i] = new BucketSizeInfo(i);<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    }<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.319"></a>
-<span class="sourceLineNo">320</span>      buckets[i] = new Bucket(bucketCapacity * i);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>      bucketSizeInfos[i &lt; this.bucketSizes.length ? i : this.bucketSizes.length - 1]<a name="line.321"></a>
-<span class="sourceLineNo">322</span>          .instantiateBucket(buckets[i]);<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    }<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    this.totalSize = ((long) buckets.length) * bucketCapacity;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    if (LOG.isInfoEnabled()) {<a name="line.325"></a>
-<span class="sourceLineNo">326</span>      LOG.info("Cache totalSize=" + this.totalSize + ", buckets=" + this.buckets.length +<a name="line.326"></a>
-<span class="sourceLineNo">327</span>        ", bucket capacity=" + this.bucketCapacity +<a name="line.327"></a>
-<span class="sourceLineNo">328</span>        "=(" + FEWEST_ITEMS_IN_BUCKET + "*" + this.bigItemSize + ")=" +<a name="line.328"></a>
-<span class="sourceLineNo">329</span>        "(FEWEST_ITEMS_IN_BUCKET*(largest configured bucketcache size))");<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 name="line.333"></a>
-<span class="sourceLineNo">334</span>   * Rebuild the allocator's data structures from a persisted map.<a name="line.334"></a>
-<span class="sourceLineNo">335</span>   * @param availableSpace capacity of cache<a name="line.335"></a>
-<span class="sourceLineNo">336</span>   * @param map A map stores the block key and BucketEntry(block's meta data<a name="line.336"></a>
-<span class="sourceLineNo">337</span>   *          like offset, length)<a name="line.337"></a>
-<span class="sourceLineNo">338</span>   * @param realCacheSize cached data size statistics for bucket cache<a name="line.338"></a>
-<span class="sourceLineNo">339</span>   * @throws BucketAllocatorException<a name="line.339"></a>
-<span class="sourceLineNo">340</span>   */<a name="line.340"></a>
-<span class="sourceLineNo">341</span>  BucketAllocator(long availableSpace, int[] bucketSizes, Map&lt;BlockCacheKey, BucketEntry&gt; map,<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      LongAdder realCacheSize) throws BucketAllocatorException {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>    this(availableSpace, bucketSizes);<a name="line.343"></a>
-<span class="sourceLineNo">344</span><a name="line.344"></a>
-<span class="sourceLineNo">345</span>    // each bucket has an offset, sizeindex. probably the buckets are too big<a name="line.345"></a>
-<span class="sourceLineNo">346</span>    // in our default state. so what we do is reconfigure them according to what<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    // we've found. we can only reconfigure each bucket once; if more than once,<a name="line.347"></a>
-<span class="sourceLineNo">348</span>    // we know there's a bug, so we just log the info, throw, and start again...<a name="line.348"></a>
-<span class="sourceLineNo">349</span>    boolean[] reconfigured = new boolean[buckets.length];<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    int sizeNotMatchedCount = 0;<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    int insufficientCapacityCount = 0;<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    Iterator&lt;Map.Entry&lt;BlockCacheKey, BucketEntry&gt;&gt; iterator = map.entrySet().iterator();<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    while (iterator.hasNext()) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>      Map.Entry&lt;BlockCacheKey, BucketEntry&gt; entry = iterator.next();<a name="line.354"></a>
-<span class="sourceLineNo">355</span>      long foundOffset = entry.getValue().offset();<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      int foundLen = entry.getValue().getLength();<a name="line.356"></a>
-<span class="sourceLineNo">357</span>      int bucketSizeIndex = -1;<a name="line.357"></a>
-<span class="sourceLineNo">358</span>      for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>        if (foundLen &lt;= this.bucketSizes[i]) {<a name="line.359"></a>
-<span class="sourceLineNo">360</span>          bucketSizeIndex = i;<a name="line.360"></a>
-<span class="sourceLineNo">361</span>          break;<a name="line.361"></a>
-<span class="sourceLineNo">362</span>        }<a name="line.362"></a>
-<span class="sourceLineNo">363</span>      }<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      if (bucketSizeIndex == -1) {<a name="line.364"></a>
-<span class="sourceLineNo">365</span>        sizeNotMatchedCount++;<a name="line.365"></a>
-<span class="sourceLineNo">366</span>        iterator.remove();<a name="line.366"></a>
-<span class="sourceLineNo">367</span>        continue;<a name="line.367"></a>
-<span class="sourceLineNo">368</span>      }<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      int bucketNo = (int) (foundOffset / bucketCapacity);<a name="line.369"></a>
-<span class="sourceLineNo">370</span>      if (bucketNo &lt; 0 || bucketNo &gt;= buckets.length) {<a name="line.370"></a>
-<span class="sourceLineNo">371</span>        insufficientCapacityCount++;<a name="line.371"></a>
-<span class="sourceLineNo">372</span>        iterator.remove();<a name="line.372"></a>
-<span class="sourceLineNo">373</span>        continue;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>      }<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      Bucket b = buckets[bucketNo];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>      if (reconfigured[bucketNo]) {<a name="line.376"></a>
-<span class="sourceLineNo">377</span>        if (b.sizeIndex() != bucketSizeIndex) {<a name="line.377"></a>
-<span class="sourceLineNo">378</span>          throw new BucketAllocatorException("Inconsistent allocation in bucket map;");<a name="line.378"></a>
-<span class="sourceLineNo">379</span>        }<a name="line.379"></a>
-<span class="sourceLineNo">380</span>      } else {<a name="line.380"></a>
-<span class="sourceLineNo">381</span>        if (!b.isCompletelyFree()) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>          throw new BucketAllocatorException(<a name="line.382"></a>
-<span class="sourceLineNo">383</span>              "Reconfiguring bucket " + bucketNo + " but it's already allocated; corrupt data");<a name="line.383"></a>
-<span class="sourceLineNo">384</span>        }<a name="line.384"></a>
-<span class="sourceLineNo">385</span>        // Need to remove the bucket from whichever list it's currently in at<a name="line.385"></a>
-<span class="sourceLineNo">386</span>        // the moment...<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        BucketSizeInfo bsi = bucketSizeInfos[bucketSizeIndex];<a name="line.387"></a>
-<span class="sourceLineNo">388</span>        BucketSizeInfo oldbsi = bucketSizeInfos[b.sizeIndex()];<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        oldbsi.removeBucket(b);<a name="line.389"></a>
-<span class="sourceLineNo">390</span>        bsi.instantiateBucket(b);<a name="line.390"></a>
-<span class="sourceLineNo">391</span>        reconfigured[bucketNo] = true;<a name="line.391"></a>
-<span class="sourceLineNo">392</span>      }<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      realCacheSize.add(foundLen);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      buckets[bucketNo].addAllocation(foundOffset);<a name="line.394"></a>
-<span class="sourceLineNo">395</span>      usedSize += buckets[bucketNo].getItemAllocationSize();<a name="line.395"></a>
-<span class="sourceLineNo">396</span>      bucketSizeInfos[bucketSizeIndex].blockAllocated(b);<a name="line.396"></a>
-<span class="sourceLineNo">397</span>    }<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    if (sizeNotMatchedCount &gt; 0) {<a name="line.399"></a>
-<span class="sourceLineNo">400</span>      LOG.warn("There are " + sizeNotMatchedCount + " blocks which can't be rebuilt because " +<a name="line.400"></a>
-<span class="sourceLineNo">401</span>        "there is no matching bucket size for these blocks");<a name="line.401"></a>
-<span class="sourceLineNo">402</span>    }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>    if (insufficientCapacityCount &gt; 0) {<a name="line.403"></a>
-<span class="sourceLineNo">404</span>      LOG.warn("There are " + insufficientCapacityCount + " blocks which can't be rebuilt - "<a name="line.404"></a>
-<span class="sourceLineNo">405</span>        + "did you shrink the cache?");<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    }<a name="line.406"></a>
-<span class="sourceLineNo">407</span>  }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>  @Override<a name="line.409"></a>
-<span class="sourceLineNo">410</span>  public String toString() {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    StringBuilder sb = new StringBuilder(1024);<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      Bucket b = buckets[i];<a name="line.413"></a>
-<span class="sourceLineNo">414</span>      if (i &gt; 0) sb.append(", ");<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      sb.append("bucket.").append(i).append(": size=").append(b.getItemAllocationSize());<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      sb.append(", freeCount=").append(b.freeCount()).append(", used=").append(b.usedCount());<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    }<a name="line.417"></a>
-<span class="sourceLineNo">418</span>    return sb.toString();<a name="line.418"></a>
-<span class="sourceLineNo">419</span>  }<a name="line.419"></a>
-<span class="sourceLineNo">420</span><a name="line.420"></a>
-<span class="sourceLineNo">421</span>  public long getUsedSize() {<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    return this.usedSize;<a name="line.422"></a>
-<span class="sourceLineNo">423</span>  }<a name="line.423"></a>
-<span class="sourceLineNo">424</span><a name="line.424"></a>
-<span class="sourceLineNo">425</span>  public long getFreeSize() {<a name="line.425"></a>
-<span class="sourceLineNo">426</span>    return this.totalSize - getUsedSize();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>  }<a name="line.427"></a>
-<span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>  public long getTotalSize() {<a name="line.429"></a>
-<span class="sourceLineNo">430</span>    return this.totalSize;<a name="line.430"></a>
-<span class="sourceLineNo">431</span>  }<a name="line.431"></a>
-<span class="sourceLineNo">432</span><a name="line.432"></a>
-<span class="sourceLineNo">433</span>  /**<a name="line.433"></a>
-<span class="sourceLineNo">434</span>   * Allocate a block with specified size. Return the offset<a name="line.434"></a>
-<span class="sourceLineNo">435</span>   * @param blockSize size of block<a name="line.435"></a>
-<span class="sourceLineNo">436</span>   * @throws BucketAllocatorException<a name="line.436"></a>
-<span class="sourceLineNo">437</span>   * @throws CacheFullException<a name="line.437"></a>
-<span class="sourceLineNo">438</span>   * @return the offset in the IOEngine<a name="line.438"></a>
-<span class="sourceLineNo">439</span>   */<a name="line.439"></a>
-<span class="sourceLineNo">440</span>  public synchronized long allocateBlock(int blockSize) throws CacheFullException,<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      BucketAllocatorException {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    assert blockSize &gt; 0;<a name="line.442"></a>
-<span class="sourceLineNo">443</span>    BucketSizeInfo bsi = roundUpToBucketSizeInfo(blockSize);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    if (bsi == null) {<a name="line.444"></a>
-<span class="sourceLineNo">445</span>      throw new BucketAllocatorException("Allocation too big size=" + blockSize +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "; adjust BucketCache sizes " + BlockCacheFactory.BUCKET_CACHE_BUCKETS_KEY +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to accomodate if size seems reasonable and you want it cached.");<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    }<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    long offset = bsi.allocateBlock();<a name="line.449"></a>
-<span class="sourceLineNo">450</span><a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // Ask caller to free up space and try again!<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    if (offset &lt; 0)<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      throw new CacheFullException(blockSize, bsi.sizeIndex());<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    usedSize += bucketSizes[bsi.sizeIndex()];<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    return offset;<a name="line.455"></a>
-<span class="sourceLineNo">456</span>  }<a name="line.456"></a>
-<span class="sourceLineNo">457</span><a name="line.457"></a>
-<span class="sourceLineNo">458</span>  private Bucket grabGlobalCompletelyFreeBucket() {<a name="line.458"></a>
-<span class="sourceLineNo">459</span>    for (BucketSizeInfo bsi : bucketSizeInfos) {<a name="line.459"></a>
-<span class="sourceLineNo">460</span>      Bucket b = bsi.findAndRemoveCompletelyFreeBucket();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>      if (b != null) return b;<a name="line.461"></a>
-<span class="sourceLineNo">462</span>    }<a name="line.462"></a>
-<span class="sourceLineNo">463</span>    return null;<a name="line.463"></a>
-<span class="sourceLineNo">464</span>  }<a name="line.464"></a>
-<span class="sourceLineNo">465</span><a name="line.465"></a>
-<span class="sourceLineNo">466</span>  /**<a name="line.466"></a>
-<span class="sourceLineNo">467</span>   * Free a block with the offset<a name="line.467"></a>
-<span class="sourceLineNo">468</span>   * @param offset block's offset<a name="line.468"></a>
-<span class="sourceLineNo">469</span>   * @return size freed<a name="line.469"></a>
-<span class="sourceLineNo">470</span>   */<a name="line.470"></a>
-<span class="sourceLineNo">471</span>  public synchronized int freeBlock(long offset) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.473"></a>
-<span class="sourceLineNo">474</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.474"></a>
-<span class="sourceLineNo">475</span>    bucketSizeInfos[targetBucket.sizeIndex()].freeBlock(targetBucket, offset);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>    usedSize -= targetBucket.getItemAllocationSize();<a name="line.476"></a>
-<span class="sourceLineNo">477</span>    return targetBucket.getItemAllocationSize();<a name="line.477"></a>
-<span class="sourceLineNo">478</span>  }<a name="line.478"></a>
-<span class="sourceLineNo">479</span><a name="line.479"></a>
-<span class="sourceLineNo">480</span>  public int sizeIndexOfAllocation(long offset) {<a name="line.480"></a>
-<span class="sourceLineNo">481</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.481"></a>
-<span class="sourceLineNo">482</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    return targetBucket.sizeIndex();<a name="line.484"></a>
-<span class="sourceLineNo">485</span>  }<a name="line.485"></a>
-<span class="sourceLineNo">486</span><a name="line.486"></a>
-<span class="sourceLineNo">487</span>  public int sizeOfAllocation(long offset) {<a name="line.487"></a>
-<span class="sourceLineNo">488</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.488"></a>
-<span class="sourceLineNo">489</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.489"></a>
-<span class="sourceLineNo">490</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    return targetBucket.getItemAllocationSize();<a name="line.491"></a>
-<span class="sourceLineNo">492</span>  }<a name="line.492"></a>
-<span class="sourceLineNo">493</span><a name="line.493"></a>
-<span class="sourceLineNo">494</span>  static class IndexStatistics {<a name="line.494"></a>
-<span class="sourceLineNo">495</span>    private long freeCount, usedCount, itemSize, totalCount;<a name="line.495"></a>
-<span class="sourceLineNo">496</span><a name="line.496"></a>
-<span class="sourceLineNo">497</span>    public long freeCount() {<a name="line.497"></a>
-<span class="sourceLineNo">498</span>      return freeCount;<a name="line.498"></a>
-<span class="sourceLineNo">499</span>    }<a name="line.499"></a>
-<span class="sourceLineNo">500</span><a name="line.500"></a>
-<span class="sourceLineNo">501</span>    public long usedCount() {<a name="line.501"></a>
-<span class="sourceLineNo">502</span>      return usedCount;<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    }<a name="line.503"></a>
-<span class="sourceLineNo">504</span><a name="line.504"></a>
-<span class="sourceLineNo">505</span>    public long totalCount() {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      return totalCount;<a name="line.506"></a>
-<span class="sourceLineNo">507</span>    }<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>    public long freeBytes() {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>      return freeCount * itemSize;<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    }<a name="line.511"></a>
-<span class="sourceLineNo">512</span><a name="line.512"></a>
-<span class="sourceLineNo">513</span>    public long usedBytes() {<a name="line.513"></a>
-<span class="sourceLineNo">514</span>      return usedCount * itemSize;<a name="line.514"></a>
-<span class="sourceLineNo">515</span>    }<a name="line.515"></a>
-<span class="sourceLineNo">516</span><a name="line.516"></a>
-<span class="sourceLineNo">517</span>    public long totalBytes() {<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      return totalCount * itemSize;<a name="line.518"></a>
-<span class="sourceLineNo">519</span>    }<a name="line.519"></a>
-<span class="sourceLineNo">520</span><a name="line.520"></a>
-<span class="sourceLineNo">521</span>    public long itemSize() {<a name="line.521"></a>
-<span class="sourceLineNo">522</span>      return itemSize;<a name="line.522"></a>
-<span class="sourceLineNo">523</span>    }<a name="line.523"></a>
-<span class="sourceLineNo">524</span><a name="line.524"></a>
-<span class="sourceLineNo">525</span>    public IndexStatistics(long free, long used, long itemSize) {<a name="line.525"></a>
-<span class="sourceLineNo">526</span>      setTo(free, used, itemSize);<a name="line.526"></a>
-<span class="sourceLineNo">527</span>    }<a name="line.527"></a>
-<span class="sourceLineNo">528</span><a name="line.528"></a>
-<span class="sourceLineNo">529</span>    public IndexStatistics() {<a name="line.529"></a>
-<span class="sourceLineNo">530</span>      setTo(-1, -1, 0);<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    }<a name="line.531"></a>
-<span class="sourceLineNo">532</span><a name="line.532"></a>
-<span class="sourceLineNo">533</span>    public void setTo(long free, long used, long itemSize) {<a name="line.533"></a>
-<span class="sourceLineNo">534</span>      this.itemSize = itemSize;<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      this.freeCount = free;<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      this.usedCount = used;<a name="line.536"></a>
-<span class="sourceLineNo">537</span>      this.totalCount = free + used;<a name="line.537"></a>
-<span class="sourceLineNo">538</span>    }<a name="line.538"></a>
-<span class="sourceLineNo">539</span>  }<a name="line.539"></a>
-<span class="sourceLineNo">540</span><a name="line.540"></a>
-<span class="sourceLineNo">541</span>  public Bucket [] getBuckets() {<a name="line.541"></a>
-<span class="sourceLineNo">542</span>    return this.buckets;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>  }<a name="line.543"></a>
-<span class="sourceLineNo">544</span><a name="line.544"></a>
-<span class="sourceLineNo">545</span>  void logStatistics() {<a name="line.545"></a>
-<span class="sourceLineNo">546</span>    IndexStatistics total = new IndexStatistics();<a name="line.546"></a>
-<span class="sourceLineNo">547</span>    IndexStatistics[] stats = getIndexStatistics(total);<a name="line.547"></a>
-<span class="sourceLineNo">548</span>    LOG.info("Bucket allocator statistics follow:\n");<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    LOG.info("  Free bytes=" + total.freeBytes() + "+; used bytes="<a name="line.549"></a>
-<span class="sourceLineNo">550</span>        + total.usedBytes() + "; total bytes=" + total.totalBytes());<a name="line.550"></a>
-<span class="sourceLineNo">551</span>    for (IndexStatistics s : stats) {<a name="line.551"></a>
-<span class="sourceLineNo">552</span>      LOG.info("  Object size " + s.itemSize() + " used=" + s.usedCount()<a name="line.552"></a>
-<span class="sourceLineNo">553</span>          + "; free=" + s.freeCount() + "; total=" + s.totalCount());<a name="line.553"></a>
-<span class="sourceLineNo">554</span>    }<a name="line.554"></a>
-<span class="sourceLineNo">555</span>  }<a name="line.555"></a>
-<span class="sourceLineNo">556</span><a name="line.556"></a>
-<span class="sourceLineNo">557</span>  IndexStatistics[] getIndexStatistics(IndexStatistics grandTotal) {<a name="line.557"></a>
-<span class="sourceLineNo">558</span>    IndexStatistics[] stats = getIndexStatistics();<a name="line.558"></a>
-<span class="sourceLineNo">559</span>    long totalfree = 0, totalused = 0;<a name="line.559"></a>
-<span class="sourceLineNo">560</span>    for (IndexStatistics stat : stats) {<a name="line.560"></a>
-<span class="sourceLineNo">561</span>      totalfree += stat.freeBytes();<a name="line.561"></a>
-<span class="sourceLineNo">562</span>      totalused += stat.usedBytes();<a name="line.562"></a>
-<span class="sourceLineNo">563</span>    }<a name="line.563"></a>
-<span class="sourceLineNo">564</span>    grandTotal.setTo(totalfree, totalused, 1);<a name="line.564"></a>
-<span class="sourceLineNo">565</span>    return stats;<a name="line.565"></a>
-<span class="sourceLineNo">566</span>  }<a name="line.566"></a>
-<span class="sourceLineNo">567</span><a name="line.567"></a>
-<span class="sourceLineNo">568</span>  IndexStatistics[] getIndexStatistics() {<a name="line.568"></a>
-<span class="sourceLineNo">569</span>    IndexStatistics[] stats = new IndexStatistics[bucketSizes.length];<a name="line.569"></a>
-<span class="sourceLineNo">570</span>    for (int i = 0; i &lt; stats.length; ++i)<a name="line.570"></a>
-<span class="sourceLineNo">571</span>      stats[i] = bucketSizeInfos[i].statistics();<a name="line.571"></a>
-<span class="sourceLineNo">572</span>    return stats;<a name="line.572"></a>
-<span class="sourceLineNo">573</span>  }<a name="line.573"></a>
-<span class="sourceLineNo">574</span><a name="line.574"></a>
-<span class="sourceLineNo">575</span>  public long freeBlock(long freeList[]) {<a name="line.575"></a>
-<span class="sourceLineNo">576</span>    long sz = 0;<a name="line.576"></a>
-<span class="sourceLineNo">577</span>    for (int i = 0; i &lt; freeList.length; ++i)<a name="line.577"></a>
-<span class="sourceLineNo">578</span>      sz += freeBlock(freeList[i]);<a name="line.578"></a>
-<span class="sourceLineNo">579</span>    return sz;<a name="line.579"></a>
-<span class="sourceLineNo">580</span>  }<a name="line.580"></a>
-<span class="sourceLineNo">581</span><a name="line.581"></a>
-<span class="sourceLineNo">582</span>  public int getBucketIndex(long offset) {<a name="line.582"></a>
-<span class="sourceLineNo">583</span>    return (int) (offset / bucketCapacity);<a name="line.583"></a>
-<span class="sourceLineNo">584</span>  }<a name="line.584"></a>
-<span class="sourceLineNo">585</span><a name="line.585"></a>
-<span class="sourceLineNo">586</span>  /**<a name="line.586"></a>
-<span class="sourceLineNo">587</span>   * Returns a set of indices of the buckets that are least filled<a name="line.587"></a>
-<span class="sourceLineNo">588</span>   * excluding the offsets, we also the fully free buckets for the<a name="line.588"></a>
-<span class="sourceLineNo">589</span>   * BucketSizes where everything is empty and they only have one<a name="line.589"></a>
-<span class="sourceLineNo">590</span>   * completely free bucket as a reserved<a name="line.590"></a>
-<span class="sourceLineNo">591</span>   *<a name="line.591"></a>
-<span class="sourceLineNo">592</span>   * @param excludedBuckets the buckets that need to be excluded due to<a name="line.592"></a>
-<span class="sourceLineNo">593</span>   *                        currently being in used<a name="line.593"></a>
-<span class="sourceLineNo">594</span>   * @param bucketCount     max Number of buckets to return<a name="line.594"></a>
-<span class="sourceLineNo">595</span>   * @return set of bucket indices which could be used for eviction<a name="line.595"></a>
-<span class="sourceLineNo">596</span>   */<a name="line.596"></a>
-<span class="sourceLineNo">597</span>  public Set&lt;Integer&gt; getLeastFilledBuckets(Set&lt;Integer&gt; excludedBuckets,<a name="line.597"></a>
-<span class="sourceLineNo">598</span>                                            int bucketCount) {<a name="line.598"></a>
-<span class="sourceLineNo">599</span>    Queue&lt;Integer&gt; queue = MinMaxPriorityQueue.&lt;Integer&gt;orderedBy(<a name="line.599"></a>
-<span class="sourceLineNo">600</span>        new Comparator&lt;Integer&gt;() {<a name="line.600"></a>
-<span class="sourceLineNo">601</span>          @Override<a name="line.601"></a>
-<span class="sourceLineNo">602</span>          public int compare(Integer left, Integer right) {<a name="line.602"></a>
-<span class="sourceLineNo">603</span>            // We will always get instantiated buckets<a name="line.603"></a>
-<span class="sourceLineNo">604</span>            return Float.compare(<a name="line.604"></a>
-<span class="sourceLineNo">605</span>                ((float) buckets[left].usedCount) / buckets[left].itemCount,<a name="line.605"></a>
-<span class="sourceLineNo">606</span>                ((float) buckets[right].usedCount) / buckets[right].itemCount);<a name="line.606"></a>
-<span class="sourceLineNo">607</span>          }<a name="line.607"></a>
-<span class="sourceLineNo">608</span>        }).maximumSize(bucketCount).create();<a name="line.608"></a>
-<span class="sourceLineNo">609</span><a name="line.609"></a>
-<span class="sourceLineNo">610</span>    for (int i = 0; i &lt; buckets.length; i ++ ) {<a name="line.610"></a>
-<span class="sourceLineNo">611</span>      if (!excludedBuckets.contains(i) &amp;&amp; !buckets[i].isUninstantiated() &amp;&amp;<a name="line.611"></a>
-<span class="sourceLineNo">612</span>          // Avoid the buckets that are the only buckets for a sizeIndex<a name="line.612"></a>
-<span class="sourceLineNo">613</span>          bucketSizeInfos[buckets[i].sizeIndex()].bucketList.size() != 1) {<a name="line.613"></a>
-<span class="sourceLineNo">614</span>        queue.add(i);<a name="line.614"></a>
-<span class="sourceLineNo">615</span>      }<a name="line.615"></a>
-<span class="sourceLineNo">616</span>    }<a name="line.616"></a>
-<span class="sourceLineNo">617</span><a name="line.617"></a>
-<span class="sourceLineNo">618</span>    Set&lt;Integer&gt; result = new HashSet&lt;&gt;(bucketCount);<a name="line.618"></a>
-<span class="sourceLineNo">619</span>    result.addAll(queue);<a name="line.619"></a>
-<span class="sourceLineNo">620</span><a name="line.620"></a>
-<span class="sourceLineNo">621</span>    return result;<a name="line.621"></a>
-<span class="sourceLineNo">622</span>  }<a name="line.622"></a>
-<span class="sourceLineNo">623</span>}<a name="line.623"></a>
+<span class="sourceLineNo">272</span>  // The real block size in hfile maybe a little larger than the size we configured ,<a name="line.272"></a>
+<span class="sourceLineNo">273</span>  // so we need add extra 1024 bytes for fit.<a name="line.273"></a>
+<span class="sourceLineNo">274</span>  // TODO Support the view of block size distribution statistics<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  private static final int DEFAULT_BUCKET_SIZES[] = { 4 * 1024 + 1024, 8 * 1024 + 1024,<a name="line.275"></a>
+<span class="sourceLineNo">276</span>      16 * 1024 + 1024, 32 * 1024 + 1024, 40 * 1024 + 1024, 48 * 1024 + 1024,<a name="line.276"></a>
+<span class="sourceLineNo">277</span>      56 * 1024 + 1024, 64 * 1024 + 1024, 96 * 1024 + 1024, 128 * 1024 + 1024,<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      192 * 1024 + 1024, 256 * 1024 + 1024, 384 * 1024 + 1024,<a name="line.278"></a>
+<span class="sourceLineNo">279</span>      512 * 1024 + 1024 };<a name="line.279"></a>
+<span class="sourceLineNo">280</span><a name="line.280"></a>
+<span class="sourceLineNo">281</span>  /**<a name="line.281"></a>
+<span class="sourceLineNo">282</span>   * Round up the given block size to bucket size, and get the corresponding<a name="line.282"></a>
+<span class="sourceLineNo">283</span>   * BucketSizeInfo<a name="line.283"></a>
+<span class="sourceLineNo">284</span>   */<a name="line.284"></a>
+<span class="sourceLineNo">285</span>  public BucketSizeInfo roundUpToBucketSizeInfo(int blockSize) {<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    for (int i = 0; i &lt; bucketSizes.length; ++i)<a name="line.286"></a>
+<span class="sourceLineNo">287</span>      if (blockSize &lt;= bucketSizes[i])<a name="line.287"></a>
+<span class="sourceLineNo">288</span>        return bucketSizeInfos[i];<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    return null;<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>  /**<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   * So, what is the minimum amount of items we'll tolerate in a single bucket?<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
+<span class="sourceLineNo">295</span>  static public final int FEWEST_ITEMS_IN_BUCKET = 4;<a name="line.295"></a>
+<span class="sourceLineNo">296</span><a name="line.296"></a>
+<span class="sourceLineNo">297</span>  private final int[] bucketSizes;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>  private final int bigItemSize;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>  // The capacity size for each bucket<a name="line.299"></a>
+<span class="sourceLineNo">300</span>  private final long bucketCapacity;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>  private Bucket[] buckets;<a name="line.301"></a>
+<span class="sourceLineNo">302</span>  private BucketSizeInfo[] bucketSizeInfos;<a name="line.302"></a>
+<span class="sourceLineNo">303</span>  private final long totalSize;<a name="line.303"></a>
+<span class="sourceLineNo">304</span>  private transient long usedSize = 0;<a name="line.304"></a>
+<span class="sourceLineNo">305</span><a name="line.305"></a>
+<span class="sourceLineNo">306</span>  BucketAllocator(long availableSpace, int[] bucketSizes)<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      throws BucketAllocatorException {<a name="line.307"></a>
+<span class="sourceLineNo">308</span>    this.bucketSizes = bucketSizes == null ? DEFAULT_BUCKET_SIZES : bucketSizes;<a name="line.308"></a>
+<span class="sourceLineNo">309</span>    Arrays.sort(this.bucketSizes);<a name="line.309"></a>
+<span class="sourceLineNo">310</span>    this.bigItemSize = Ints.max(this.bucketSizes);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    this.bucketCapacity = FEWEST_ITEMS_IN_BUCKET * (long) bigItemSize;<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    buckets = new Bucket[(int) (availableSpace / bucketCapacity)];<a name="line.312"></a>
+<span class="sourceLineNo">313</span>    if (buckets.length &lt; this.bucketSizes.length)<a name="line.313"></a>
+<span class="sourceLineNo">314</span>      throw new BucketAllocatorException("Bucket allocator size too small (" + buckets.length +<a name="line.314"></a>
+<span class="sourceLineNo">315</span>        "); must have room for at least " + this.bucketSizes.length + " buckets");<a name="line.315"></a>
+<span class="sourceLineNo">316</span>    bucketSizeInfos = new BucketSizeInfo[this.bucketSizes.length];<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>      bucketSizeInfos[i] = new BucketSizeInfo(i);<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    }<a name="line.319"></a>
+<span class="sourceLineNo">320</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.320"></a>
+<span class="sourceLineNo">321</span>      buckets[i] = new Bucket(bucketCapacity * i);<a name="line.321"></a>
+<span class="sourceLineNo">322</span>      bucketSizeInfos[i &lt; this.bucketSizes.length ? i : this.bucketSizes.length - 1]<a name="line.322"></a>
+<span class="sourceLineNo">323</span>          .instantiateBucket(buckets[i]);<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    }<a name="line.324"></a>
+<span class="sourceLineNo">325</span>    this.totalSize = ((long) buckets.length) * bucketCapacity;<a name="line.325"></a>
+<span class="sourceLineNo">326</span>    if (LOG.isInfoEnabled()) {<a name="line.326"></a>
+<span class="sourceLineNo">327</span>      LOG.info("Cache totalSize=" + this.totalSize + ", buckets=" + this.buckets.length +<a name="line.327"></a>
+<span class="sourceLineNo">328</span>        ", bucket capacity=" + this.bucketCapacity +<a name="line.328"></a>
+<span class="sourceLineNo">329</span>        "=(" + FEWEST_ITEMS_IN_BUCKET + "*" + this.bigItemSize + ")=" +<a name="line.329"></a>
+<span class="sourceLineNo">330</span>        "(FEWEST_ITEMS_IN_BUCKET*(largest configured bucketcache size))");<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 name="line.333"></a>
+<span class="sourceLineNo">334</span>  /**<a name="line.334"></a>
+<span class="sourceLineNo">335</span>   * Rebuild the allocator's data structures from a persisted map.<a name="line.335"></a>
+<span class="sourceLineNo">336</span>   * @param availableSpace capacity of cache<a name="line.336"></a>
+<span class="sourceLineNo">337</span>   * @param map A map stores the block key and BucketEntry(block's meta data<a name="line.337"></a>
+<span class="sourceLineNo">338</span>   *          like offset, length)<a name="line.338"></a>
+<span class="sourceLineNo">339</span>   * @param realCacheSize cached data size statistics for bucket cache<a name="line.339"></a>
+<span class="sourceLineNo">340</span>   * @throws BucketAllocatorException<a name="line.340"></a>
+<span class="sourceLineNo">341</span>   */<a name="line.341"></a>
+<span class="sourceLineNo">342</span>  BucketAllocator(long availableSpace, int[] bucketSizes, Map&lt;BlockCacheKey, BucketEntry&gt; map,<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      LongAdder realCacheSize) throws BucketAllocatorException {<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    this(availableSpace, bucketSizes);<a name="line.344"></a>
+<span class="sourceLineNo">345</span><a name="line.345"></a>
+<span class="sourceLineNo">346</span>    // each bucket has an offset, sizeindex. probably the buckets are too big<a name="line.346"></a>
+<span class="sourceLineNo">347</span>    // in our default state. so what we do is reconfigure them according to what<a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // we've found. we can only reconfigure each bucket once; if more than once,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // we know there's a bug, so we just log the info, throw, and start again...<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    boolean[] reconfigured = new boolean[buckets.length];<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    int sizeNotMatchedCount = 0;<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    int insufficientCapacityCount = 0;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    Iterator&lt;Map.Entry&lt;BlockCacheKey, BucketEntry&gt;&gt; iterator = map.entrySet().iterator();<a name="line.353"></a>
+<span class="sourceLineNo">354</span>    while (iterator.hasNext()) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      Map.Entry&lt;BlockCacheKey, BucketEntry&gt; entry = iterator.next();<a name="line.355"></a>
+<span class="sourceLineNo">356</span>      long foundOffset = entry.getValue().offset();<a name="line.356"></a>
+<span class="sourceLineNo">357</span>      int foundLen = entry.getValue().getLength();<a name="line.357"></a>
+<span class="sourceLineNo">358</span>      int bucketSizeIndex = -1;<a name="line.358"></a>
+<span class="sourceLineNo">359</span>      for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.359"></a>
+<span class="sourceLineNo">360</span>        if (foundLen &lt;= this.bucketSizes[i]) {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>          bucketSizeIndex = i;<a name="line.361"></a>
+<span class="sourceLineNo">362</span>          break;<a name="line.362"></a>
+<span class="sourceLineNo">363</span>        }<a name="line.363"></a>
+<span class="sourceLineNo">364</span>      }<a name="line.364"></a>
+<span class="sourceLineNo">365</span>      if (bucketSizeIndex == -1) {<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        sizeNotMatchedCount++;<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        iterator.remove();<a name="line.367"></a>
+<span class="sourceLineNo">368</span>        continue;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>      }<a name="line.369"></a>
+<span class="sourceLineNo">370</span>      int bucketNo = (int) (foundOffset / bucketCapacity);<a name="line.370"></a>
+<span class="sourceLineNo">371</span>      if (bucketNo &lt; 0 || bucketNo &gt;= buckets.length) {<a name="line.371"></a>
+<span class="sourceLineNo">372</span>        insufficientCapacityCount++;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>        iterator.remove();<a name="line.373"></a>
+<span class="sourceLineNo">374</span>        continue;<a name="line.374"></a>
+<span class="sourceLineNo">375</span>      }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>      Bucket b = buckets[bucketNo];<a name="line.376"></a>
+<span class="sourceLineNo">377</span>      if (reconfigured[bucketNo]) {<a name="line.377"></a>
+<span class="sourceLineNo">378</span>        if (b.sizeIndex() != bucketSizeIndex) {<a name="line.378"></a>
+<span class="sourceLineNo">379</span>          throw new BucketAllocatorException("Inconsistent allocation in bucket map;");<a name="line.379"></a>
+<span class="sourceLineNo">380</span>        }<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      } else {<a name="line.381"></a>
+<span class="sourceLineNo">382</span>        if (!b.isCompletelyFree()) {<a name="line.382"></a>
+<span class="sourceLineNo">383</span>          throw new BucketAllocatorException(<a name="line.383"></a>
+<span class="sourceLineNo">384</span>              "Reconfiguring bucket " + bucketNo + " but it's already allocated; corrupt data");<a name="line.384"></a>
+<span class="sourceLineNo">385</span>        }<a name="line.385"></a>
+<span class="sourceLineNo">386</span>        // Need to remove the bucket from whichever list it's currently in at<a name="line.386"></a>
+<span class="sourceLineNo">387</span>        // the moment...<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        BucketSizeInfo bsi = bucketSizeInfos[bucketSizeIndex];<a name="line.388"></a>
+<span class="sourceLineNo">389</span>        BucketSizeInfo oldbsi = bucketSizeInfos[b.sizeIndex()];<a name="line.389"></a>
+<span class="sourceLineNo">390</span>        oldbsi.removeBucket(b);<a name="line.390"></a>
+<span class="sourceLineNo">391</span>        bsi.instantiateBucket(b);<a name="line.391"></a>
+<span class="sourceLineNo">392</span>        reconfigured[bucketNo] = true;<a name="line.392"></a>
+<span class="sourceLineNo">393</span>      }<a name="line.393"></a>
+<span class="sourceLineNo">394</span>      realCacheSize.add(foundLen);<a name="line.394"></a>
+<span class="sourceLineNo">395</span>      buckets[bucketNo].addAllocation(foundOffset);<a name="line.395"></a>
+<span class="sourceLineNo">396</span>      usedSize += buckets[bucketNo].getItemAllocationSize();<a name="line.396"></a>
+<span class="sourceLineNo">397</span>      bucketSizeInfos[bucketSizeIndex].blockAllocated(b);<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    }<a name="line.398"></a>
+<span class="sourceLineNo">399</span><a name="line.399"></a>
+<span class="sourceLineNo">400</span>    if (sizeNotMatchedCount &gt; 0) {<a name="line.400"></a>
+<span class="sourceLineNo">401</span>      LOG.warn("There are " + sizeNotMatchedCount + " blocks which can't be rebuilt because " +<a name="line.401"></a>
+<span class="sourceLineNo">402</span>        "there is no matching bucket size for these blocks");<a name="line.402"></a>
+<span class="sourceLineNo">403</span>    }<a name="line.403"></a>
+<span class="sourceLineNo">404</span>    if (insufficientCapacityCount &gt; 0) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>      LOG.warn("There are " + insufficientCapacityCount + " blocks which can't be rebuilt - "<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        + "did you shrink the cache?");<a name="line.406"></a>
+<span class="sourceLineNo">407</span>    }<a name="line.407"></a>
+<span class="sourceLineNo">408</span>  }<a name="line.408"></a>
+<span class="sourceLineNo">409</span><a name="line.409"></a>
+<span class="sourceLineNo">410</span>  @Override<a name="line.410"></a>
+<span class="sourceLineNo">411</span>  public String toString() {<a name="line.411"></a>
+<span class="sourceLineNo">412</span>    StringBuilder sb = new StringBuilder(1024);<a name="line.412"></a>
+<span class="sourceLineNo">413</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      Bucket b = buckets[i];<a name="line.414"></a>
+<span class="sourceLineNo">415</span>      if (i &gt; 0) sb.append(", ");<a name="line.415"></a>
+<span class="sourceLineNo">416</span>      sb.append("bucket.").append(i).append(": size=").append(b.getItemAllocationSize());<a name="line.416"></a>
+<span class="sourceLineNo">417</span>      sb.append(", freeCount=").append(b.freeCount()).append(", used=").append(b.usedCount());<a name="line.417"></a>
+<span class="sourceLineNo">418</span>    }<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    return sb.toString();<a name="line.419"></a>
+<span class="sourceLineNo">420</span>  }<a name="line.420"></a>
+<span class="sourceLineNo">421</span><a name="line.421"></a>
+<span class="sourceLineNo">422</span>  public long getUsedSize() {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    return this.usedSize;<a name="line.423"></a>
+<span class="sourceLineNo">424</span>  }<a name="line.424"></a>
+<span class="sourceLineNo">425</span><a name="line.425"></a>
+<span class="sourceLineNo">426</span>  public long getFreeSize() {<a name="line.426"></a>
+<span class="sourceLineNo">427</span>    return this.totalSize - getUsedSize();<a name="line.427"></a>
+<span class="sourceLineNo">428</span>  }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>  public long getTotalSize() {<a name="line.430"></a>
+<span class="sourceLineNo">431</span>    return this.totalSize;<a name="line.431"></a>
+<span class="sourceLineNo">432</span>  }<a name="line.432"></a>
+<span class="sourceLineNo">433</span><a name="line.433"></a>
+<span class="sourceLineNo">434</span>  /**<a name="line.434"></a>
+<span class="sourceLineNo">435</span>   * Allocate a block with specified size. Return the offset<a name="line.435"></a>
+<span class="sourceLineNo">436</span>   * @param blockSize size of block<a name="line.436"></a>
+<span class="sourceLineNo">437</span>   * @throws BucketAllocatorException<a name="line.437"></a>
+<span class="sourceLineNo">438</span>   * @throws CacheFullException<a name="line.438"></a>
+<span class="sourceLineNo">439</span>   * @return the offset in the IOEngine<a name="line.439"></a>
+<span class="sourceLineNo">440</span>   */<a name="line.440"></a>
+<span class="sourceLineNo">441</span>  public synchronized long allocateBlock(int blockSize) throws CacheFullException,<a name="line.441"></a>
+<span class="sourceLineNo">442</span>      BucketAllocatorException {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>    assert blockSize &gt; 0;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>    BucketSizeInfo bsi = roundUpToBucketSizeInfo(blockSize);<a name="line.444"></a>
+<span class="sourceLineNo">445</span>    if (bsi == null) {<a name="line.445"></a>
+<span class="sourceLineNo">446</span>      throw new BucketAllocatorException("Allocation too big size=" + blockSize +<a name="line.446"></a>
+<span class="sourceLineNo">447</span>        "; adjust BucketCache sizes " + BlockCacheFactory.BUCKET_CACHE_BUCKETS_KEY +<a name="line.447"></a>
+<span class="sourceLineNo">448</span>        " to accomodate if size seems reasonable and you want it cached.");<a name="line.448"></a>
+<span class="sourceLineNo">449</span>    }<a name="line.449"></a>
+<span class="sourceLineNo">450</span>    long offset = bsi.allocateBlock();<a name="line.450"></a>
+<span class="sourceLineNo">451</span><a name="line.451"></a>
+<span class="sourceLineNo">452</span>    // Ask caller to free up space and try again!<a name="line.452"></a>
+<span class="sourceLineNo">453</span>    if (offset &lt; 0)<a name="line.453"></a>
+<span class="sourceLineNo">454</span>      throw new CacheFullException(blockSize, bsi.sizeIndex());<a name="line.454"></a>
+<span class="sourceLineNo">455</span>    usedSize += bucketSizes[bsi.sizeIndex()];<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    return offset;<a name="line.456"></a>
+<span class="sourceLineNo">457</span>  }<a name="line.457"></a>
+<span class="sourceLineNo">458</span><a name="line.458"></a>
+<span class="sourceLineNo">459</span>  private Bucket grabGlobalCompletelyFreeBucket() {<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    for (BucketSizeInfo bsi : bucketSizeInfos) {<a name="line.460"></a>
+<span class="sourceLineNo">461</span>      Bucket b = bsi.findAndRemoveCompletelyFreeBucket();<a name="line.461"></a>
+<span class="sourceLineNo">462</span>      if (b != null) return b;<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    }<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    return null;<a name="line.464"></a>
+<span class="sourceLineNo">465</span>  }<a name="line.465"></a>
+<span class="sourceLineNo">466</span><a name="line.466"></a>
+<span class="sourceLineNo">467</span>  /**<a name="line.467"></a>
+<span class="sourceLineNo">468</span>   * Free a block with the offset<a name="line.468"></a>
+<span class="sourceLineNo">469</span>   * @param offset block's offset<a name="line.469"></a>
+<span class="sourceLineNo">470</span>   * @return size freed<a name="line.470"></a>
+<span class="sourceLineNo">471</span>   */<a name="line.471"></a>
+<span class="sourceLineNo">472</span>  public synchronized int freeBlock(long offset) {<a name="line.472"></a>
+<span class="sourceLineNo">473</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.473"></a>
+<span class="sourceLineNo">474</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.474"></a>
+<span class="sourceLineNo">475</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.475"></a>
+<span class="sourceLineNo">476</span>    bucketSizeInfos[targetBucket.sizeIndex()].freeBlock(targetBucket, offset);<a name="line.476"></a>
+<span class="sourceLineNo">477</span>    usedSize -= targetBucket.getItemAllocationSize();<a name="line.477"></a>
+<span class="sourceLineNo">478</span>    return targetBucket.getItemAllocationSize();<a name="line.478"></a>
+<span class="sourceLineNo">479</span>  }<a name="line.479"></a>
+<span class="sourceLineNo">480</span><a name="line.480"></a>
+<span class="sourceLineNo">481</span>  public int sizeIndexOfAllocation(long offset) {<a name="line.481"></a>
+<span class="sourceLineNo">482</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.482"></a>
+<span class="sourceLineNo">483</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.483"></a>
+<span class="sourceLineNo">484</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.484"></a>
+<span class="sourceLineNo">485</span>    return targetBucket.sizeIndex();<a name="line.485"></a>
+<span class="sourceLineNo">486</span>  }<a name="line.486"></a>
+<span class="sourceLineNo">487</span><a name="line.487"></a>
+<span class="sourceLineNo">488</span>  public int sizeOfAllocation(long offset) {<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.489"></a>
+<span class="sourceLineNo">490</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.490"></a>
+<span class="sourceLineNo">491</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.491"></a>
+<span class="sourceLineNo">492</span>    return targetBucket.getItemAllocationSize();<a name="line.492"></a>
+<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
+<span class="sourceLineNo">494</span><a name="line.494"></a>
+<span class="sourceLineNo">495</span>  static class IndexStatistics {<a name="line.495"></a>
+<span class="sourceLineNo">496</span>    private long freeCount, usedCount, itemSize, totalCount;<a name="line.496"></a>
+<span class="sourceLineNo">497</span><a name="line.497"></a>
+<span class="sourceLineNo">498</span>    public long freeCount() {<a name="line.498"></a>
+<span class="sourceLineNo">499</span>      return freeCount;<a name="line.499"></a>
+<span class="sourceLineNo">500</span>    }<a name="line.500"></a>
+<span class="sourceLineNo">501</span><a name="line.501"></a>
+<span class="sourceLineNo">502</span>    public long usedCount() {<a name="line.502"></a>
+<span class="sourceLineNo">503</span>      return usedCount;<a name="line.503"></a>
+<span class="sourceLineNo">504</span>    }<a name="line.504"></a>
+<span class="sourceLineNo">505</span><a name="line.505"></a>
+<span class="sourceLineNo">506</span>    public long totalCount() {<a name="line.506"></a>
+<span class="sourceLineNo">507</span>      return totalCount;<a name="line.507"></a>
+<span class="sourceLineNo">508</span>    }<a name="line.508"></a>
+<span class="sourceLineNo">509</span><a name="line.509"></a>
+<span class="sourceLineNo">510</span>    public long freeBytes() {<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      return freeCount * itemSize;<a name="line.511"></a>
+<span class="sourceLineNo">512</span>    }<a name="line.512"></a>
+<span class="sourceLineNo">513</span><a name="line.513"></a>
+<span class="sourceLineNo">514</span>    public long usedBytes() {<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      return usedCount * itemSize;<a name="line.515"></a>
+<span class="sourceLineNo">516</span>    }<a name="line.516"></a>
+<span class="sourceLineNo">517</span><a name="line.517"></a>
+<span class="sourceLineNo">518</span>    public long totalBytes() {<a name="line.518"></a>
+<span class="sourceLineNo">519</span>      return totalCount * itemSize;<a name="line.519"></a>
+<span class="sourceLineNo">520</span>    }<a name="line.520"></a>
+<span class="sourceLineNo">521</span><a name="line.521"></a>
+<span class="sourceLineNo">522</span>    public long itemSize() {<a name="line.522"></a>
+<span class="sourceLineNo">523</span>      return itemSize;<a name="line.523"></a>
+<span class="sourceLineNo">524</span>    }<a name="line.524"></a>
+<span class="sourceLineNo">525</span><a name="line.525"></a>
+<span class="sourceLineNo">526</span>    public IndexStatistics(long free, long used, long itemSize) {<a name="line.526"></a>
+<span class="sourceLineNo">527</span>      setTo(free, used, itemSize);<a name="line.527"></a>
+<span class="sourceLineNo">528</span>    }<a name="line.528"></a>
+<span class="sourceLineNo">529</span><a name="line.529"></a>
+<span class="sourceLineNo">530</span>    public IndexStatistics() {<a name="line.530"></a>
+<span class="sourceLineNo">531</span>      setTo(-1, -1, 0);<a name="line.531"></a>
+<span class="sourceLineNo">532</span>    }<a name="line.532"></a>
+<span class="sourceLineNo">533</span><a name="line.533"></a>
+<span class="sourceLineNo">534</span>    public void setTo(long free, long used, long itemSize) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>      this.itemSize = itemSize;<a name="line.535"></a>
+<span class="sourceLineNo">536</span>      this.freeCount = free;<a name="line.536"></a>
+<span class="sourceLineNo">537</span>      this.usedCount = used;<a name="line.537"></a>
+<span class="sourceLineNo">538</span>      this.totalCount = free + used;<a name="line.538"></a>
+<span class="sourceLineNo">539</span>    }<a name="line.539"></a>
+<span class="sourceLineNo">540</span>  }<a name="line.540"></a>
+<span class="sourceLineNo">541</span><a name="line.541"></a>
+<span class="sourceLineNo">542</span>  public Bucket [] getBuckets() {<a name="line.542"></a>
+<span class="sourceLineNo">543</span>    return this.buckets;<a name="line.543"></a>
+<span class="sourceLineNo">544</span>  }<a name="line.544"></a>
+<span class="sourceLineNo">545</span><a name="line.545"></a>
+<span class="sourceLineNo">546</span>  void logStatistics() {<a name="line.546"></a>
+<span class="sourceLineNo">547</span>    IndexStatistics total = new IndexStatistics();<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    IndexStatistics[] stats = getIndexStatistics(total);<a name="line.548"></a>
+<span class="sourceLineNo">549</span>    LOG.info("Bucket allocator statistics follow:\n");<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    LOG.info("  Free bytes=" + total.freeBytes() + "+; used bytes="<a name="line.550"></a>
+<span class="sourceLineNo">551</span>        + total.usedBytes() + "; total bytes=" + total.totalBytes());<a name="line.551"></a>
+<span class="sourceLineNo">552</span>    for (IndexStatistics s : stats) {<a name="line.552"></a>
+<span class="sourceLineNo">553</span>      LOG.info("  Object size " + s.itemSize() + " used=" + s.usedCount()<a name="line.553"></a>
+<span class="sourceLineNo">554</span>          + "; free=" + s.freeCount() + "; total=" + s.totalCount());<a name="line.554"></a>
+<span class="sourceLineNo">555</span>    }<a name="line.555"></a>
+<span class="sourceLineNo">556</span>  }<a name="line.556"></a>
+<span class="sourceLineNo">557</span><a name="line.557"></a>
+<span class="sourceLineNo">558</span>  IndexStatistics[] getIndexStatistics(IndexStatistics grandTotal) {<a name="line.558"></a>
+<span class="sourceLineNo">559</span>    IndexStatistics[] stats = getIndexStatistics();<a name="line.559"></a>
+<span class="sourceLineNo">560</span>    long totalfree = 0, totalused = 0;<a name="line.560"></a>
+<span class="sourceLineNo">561</span>    for (IndexStatistics stat : stats) {<a name="line.561"></a>
+<span class="sourceLineNo">562</span>      totalfree += stat.freeBytes();<a name="line.562"></a>
+<span class="sourceLineNo">563</span>      totalused += stat.usedBytes();<a name="line.563"></a>
+<span class="sourceLineNo">564</span>    }<a name="line.564"></a>
+<span class="sourceLineNo">565</span>    grandTotal.setTo(totalfree, totalused, 1);<a name="line.565"></a>
+<span class="sourceLineNo">566</span>    return stats;<a name="line.566"></a>
+<span class="sourceLineNo">567</span>  }<a name="line.567"></a>
+<span class="sourceLineNo">568</span><a name="line.568"></a>
+<span class="sourceLineNo">569</span>  IndexStatistics[] getIndexStatistics() {<a name="line.569"></a>
+<span class="sourceLineNo">570</span>    IndexStatistics[] stats = new IndexStatistics[bucketSizes.length];<a name="line.570"></a>
+<span class="sourceLineNo">571</span>    for (int i = 0; i &lt; stats.length; ++i)<a name="line.571"></a>
+<span class="sourceLineNo">572</span>      stats[i] = bucketSizeInfos[i].statistics();<a name="line.572"></a>
+<span class="sourceLineNo">573</span>    return stats;<a name="line.573"></a>
+<span class="sourceLineNo">574</span>  }<a name="line.574"></a>
+<span class="sourceLineNo">575</span><a name="line.575"></a>
+<span class="sourceLineNo">576</span>  public long freeBlock(long freeList[]) {<a name="line.576"></a>
+<span class="sourceLineNo">577</span>    long sz = 0;<a name="line.577"></a>
+<span class="sourceLineNo">578</span>    for (int i = 0; i &lt; freeList.length; ++i)<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      sz += freeBlock(freeList[i]);<a name="line.579"></a>
+<span class="sourceLineNo">580</span>    return sz;<a name="line.580"></a>
+<span class="sourceLineNo">581</span>  }<a name="line.581"></a>
+<span class="sourceLineNo">582</span><a name="line.582"></a>
+<span class="sourceLineNo">583</span>  public int getBucketIndex(long offset) {<a name="line.583"></a>
+<span class="sourceLineNo">584</span>    return (int) (offset / bucketCapacity);<a name="line.584"></a>
+<span class="sourceLineNo">585</span>  }<a name="line.585"></a>
+<span class="sourceLineNo">586</span><a name="line.586"></a>
+<span class="sourceLineNo">587</span>  /**<a name="line.587"></a>
+<span class="sourceLineNo">588</span>   * Returns a set of indices of the buckets that are least filled<a name="line.588"></a>
+<span class="sourceLineNo">589</span>   * excluding the offsets, we also the fully free buckets for the<a name="line.589"></a>
+<span class="sourceLineNo">590</span>   * BucketSizes where everything is empty and they only have one<a name="line.590"></a>
+<span class="sourceLineNo">591</span>   * completely free bucket as a reserved<a name="line.591"></a>
+<span class="sourceLineNo">592</span>   *<a name="line.592"></a>
+<span class="sourceLineNo">593</span>   * @param excludedBuckets the buckets that need to be excluded due to<a name="line.593"></a>
+<span class="sourceLineNo">594</span>   *                        currently being in used<a name="line.594"></a>
+<span class="sourceLineNo">595</span>   * @param bucketCount     max Number of buckets to return<a name="line.595"></a>
+<span class="sourceLineNo">596</span>   * @return set of bucket indices which could be used for eviction<a name="line.596"></a>
+<span class="sourceLineNo">597</span>   */<a name="line.597"></a>
+<span class="sourceLineNo">598</span>  public Set&lt;Integer&gt; getLeastFilledBuckets(Set&lt;Integer&gt; excludedBuckets,<a name="line.598"></a>
+<span class="sourceLineNo">599</span>                                            int bucketCount) {<a name="line.599"></a>
+<span class="sourceLineNo">600</span>    Queue&lt;Integer&gt; queue = MinMaxPriorityQueue.&lt;Integer&gt;orderedBy(<a name="line.600"></a>
+<span class="sourceLineNo">601</span>        new Comparator&lt;Integer&gt;() {<a name="line.601"></a>
+<span class="sourceLineNo">602</span>          @Override<a name="line.602"></a>
+<span class="sourceLineNo">603</span>          public int compare(Integer left, Integer right) {<a name="line.603"></a>
+<span class="sourceLineNo">604</span>            // We will always get instantiated buckets<a name="line.604"></a>
+<span class="sourceLineNo">605</span>            return Float.compare(<a name="line.605"></a>
+<span class="sourceLineNo">606</span>                ((float) buckets[left].usedCount) / buckets[left].itemCount,<a name="line.606"></a>
+<span class="sourceLineNo">607</span>                ((float) buckets[right].usedCount) / buckets[right].itemCount);<a name="line.607"></a>
+<span class="sourceLineNo">608</span>          }<a name="line.608"></a>
+<span class="sourceLineNo">609</span>        }).maximumSize(bucketCount).create();<a name="line.609"></a>
+<span class="sourceLineNo">610</span><a name="line.610"></a>
+<span class="sourceLineNo">611</span>    for (int i = 0; i &lt; buckets.length; i ++ ) {<a name="line.611"></a>
+<span class="sourceLineNo">612</span>      if (!excludedBuckets.contains(i) &amp;&amp; !buckets[i].isUninstantiated() &amp;&amp;<a name="line.612"></a>
+<span class="sourceLineNo">613</span>          // Avoid the buckets that are the only buckets for a sizeIndex<a name="line.613"></a>
+<span class="sourceLineNo">614</span>          bucketSizeInfos[buckets[i].sizeIndex()].bucketList.size() != 1) {<a name="line.614"></a>
+<span class="sourceLineNo">615</span>        queue.add(i);<a name="line.615"></a>
+<span class="sourceLineNo">616</span>      }<a name="line.616"></a>
+<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
+<span class="sourceLineNo">618</span><a name="line.618"></a>
+<span class="sourceLineNo">619</span>    Set&lt;Integer&gt; result = new HashSet&lt;&gt;(bucketCount);<a name="line.619"></a>
+<span class="sourceLineNo">620</span>    result.addAll(queue);<a name="line.620"></a>
+<span class="sourceLineNo">621</span><a name="line.621"></a>
+<span class="sourceLineNo">622</span>    return result;<a name="line.622"></a>
+<span class="sourceLineNo">623</span>  }<a name="line.623"></a>
+<span class="sourceLineNo">624</span>}<a name="line.624"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.BucketSizeInfo.html b/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.BucketSizeInfo.html
index a3cd853..0a4475b 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.BucketSizeInfo.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.BucketSizeInfo.html
@@ -277,358 +277,359 @@
 <span class="sourceLineNo">269</span><a name="line.269"></a>
 <span class="sourceLineNo">270</span>  // Default block size in hbase is 64K, so we choose more sizes near 64K, you'd better<a name="line.270"></a>
 <span class="sourceLineNo">271</span>  // reset it according to your cluster's block size distribution<a name="line.271"></a>
-<span class="sourceLineNo">272</span>  // TODO Support the view of block size distribution statistics<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  // TODO: Why we add the extra 1024 bytes? Slop?<a name="line.273"></a>
-<span class="sourceLineNo">274</span>  private static final int DEFAULT_BUCKET_SIZES[] = { 4 * 1024 + 1024, 8 * 1024 + 1024,<a name="line.274"></a>
-<span class="sourceLineNo">275</span>      16 * 1024 + 1024, 32 * 1024 + 1024, 40 * 1024 + 1024, 48 * 1024 + 1024,<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      56 * 1024 + 1024, 64 * 1024 + 1024, 96 * 1024 + 1024, 128 * 1024 + 1024,<a name="line.276"></a>
-<span class="sourceLineNo">277</span>      192 * 1024 + 1024, 256 * 1024 + 1024, 384 * 1024 + 1024,<a name="line.277"></a>
-<span class="sourceLineNo">278</span>      512 * 1024 + 1024 };<a name="line.278"></a>
-<span class="sourceLineNo">279</span><a name="line.279"></a>
-<span class="sourceLineNo">280</span>  /**<a name="line.280"></a>
-<span class="sourceLineNo">281</span>   * Round up the given block size to bucket size, and get the corresponding<a name="line.281"></a>
-<span class="sourceLineNo">282</span>   * BucketSizeInfo<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   */<a name="line.283"></a>
-<span class="sourceLineNo">284</span>  public BucketSizeInfo roundUpToBucketSizeInfo(int blockSize) {<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    for (int i = 0; i &lt; bucketSizes.length; ++i)<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      if (blockSize &lt;= bucketSizes[i])<a name="line.286"></a>
-<span class="sourceLineNo">287</span>        return bucketSizeInfos[i];<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    return null;<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>   * So, what is the minimum amount of items we'll tolerate in a single bucket?<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   */<a name="line.293"></a>
-<span class="sourceLineNo">294</span>  static public final int FEWEST_ITEMS_IN_BUCKET = 4;<a name="line.294"></a>
-<span class="sourceLineNo">295</span><a name="line.295"></a>
-<span class="sourceLineNo">296</span>  private final int[] bucketSizes;<a name="line.296"></a>
-<span class="sourceLineNo">297</span>  private final int bigItemSize;<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  // The capacity size for each bucket<a name="line.298"></a>
-<span class="sourceLineNo">299</span>  private final long bucketCapacity;<a name="line.299"></a>
-<span class="sourceLineNo">300</span>  private Bucket[] buckets;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>  private BucketSizeInfo[] bucketSizeInfos;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>  private final long totalSize;<a name="line.302"></a>
-<span class="sourceLineNo">303</span>  private transient long usedSize = 0;<a name="line.303"></a>
-<span class="sourceLineNo">304</span><a name="line.304"></a>
-<span class="sourceLineNo">305</span>  BucketAllocator(long availableSpace, int[] bucketSizes)<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      throws BucketAllocatorException {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>    this.bucketSizes = bucketSizes == null ? DEFAULT_BUCKET_SIZES : bucketSizes;<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    Arrays.sort(this.bucketSizes);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>    this.bigItemSize = Ints.max(this.bucketSizes);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>    this.bucketCapacity = FEWEST_ITEMS_IN_BUCKET * (long) bigItemSize;<a name="line.310"></a>
-<span class="sourceLineNo">311</span>    buckets = new Bucket[(int) (availableSpace / bucketCapacity)];<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    if (buckets.length &lt; this.bucketSizes.length)<a name="line.312"></a>
-<span class="sourceLineNo">313</span>      throw new BucketAllocatorException("Bucket allocator size too small (" + buckets.length +<a name="line.313"></a>
-<span class="sourceLineNo">314</span>        "); must have room for at least " + this.bucketSizes.length + " buckets");<a name="line.314"></a>
-<span class="sourceLineNo">315</span>    bucketSizeInfos = new BucketSizeInfo[this.bucketSizes.length];<a name="line.315"></a>
-<span class="sourceLineNo">316</span>    for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      bucketSizeInfos[i] = new BucketSizeInfo(i);<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    }<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.319"></a>
-<span class="sourceLineNo">320</span>      buckets[i] = new Bucket(bucketCapacity * i);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>      bucketSizeInfos[i &lt; this.bucketSizes.length ? i : this.bucketSizes.length - 1]<a name="line.321"></a>
-<span class="sourceLineNo">322</span>          .instantiateBucket(buckets[i]);<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    }<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    this.totalSize = ((long) buckets.length) * bucketCapacity;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    if (LOG.isInfoEnabled()) {<a name="line.325"></a>
-<span class="sourceLineNo">326</span>      LOG.info("Cache totalSize=" + this.totalSize + ", buckets=" + this.buckets.length +<a name="line.326"></a>
-<span class="sourceLineNo">327</span>        ", bucket capacity=" + this.bucketCapacity +<a name="line.327"></a>
-<span class="sourceLineNo">328</span>        "=(" + FEWEST_ITEMS_IN_BUCKET + "*" + this.bigItemSize + ")=" +<a name="line.328"></a>
-<span class="sourceLineNo">329</span>        "(FEWEST_ITEMS_IN_BUCKET*(largest configured bucketcache size))");<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 name="line.333"></a>
-<span class="sourceLineNo">334</span>   * Rebuild the allocator's data structures from a persisted map.<a name="line.334"></a>
-<span class="sourceLineNo">335</span>   * @param availableSpace capacity of cache<a name="line.335"></a>
-<span class="sourceLineNo">336</span>   * @param map A map stores the block key and BucketEntry(block's meta data<a name="line.336"></a>
-<span class="sourceLineNo">337</span>   *          like offset, length)<a name="line.337"></a>
-<span class="sourceLineNo">338</span>   * @param realCacheSize cached data size statistics for bucket cache<a name="line.338"></a>
-<span class="sourceLineNo">339</span>   * @throws BucketAllocatorException<a name="line.339"></a>
-<span class="sourceLineNo">340</span>   */<a name="line.340"></a>
-<span class="sourceLineNo">341</span>  BucketAllocator(long availableSpace, int[] bucketSizes, Map&lt;BlockCacheKey, BucketEntry&gt; map,<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      LongAdder realCacheSize) throws BucketAllocatorException {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>    this(availableSpace, bucketSizes);<a name="line.343"></a>
-<span class="sourceLineNo">344</span><a name="line.344"></a>
-<span class="sourceLineNo">345</span>    // each bucket has an offset, sizeindex. probably the buckets are too big<a name="line.345"></a>
-<span class="sourceLineNo">346</span>    // in our default state. so what we do is reconfigure them according to what<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    // we've found. we can only reconfigure each bucket once; if more than once,<a name="line.347"></a>
-<span class="sourceLineNo">348</span>    // we know there's a bug, so we just log the info, throw, and start again...<a name="line.348"></a>
-<span class="sourceLineNo">349</span>    boolean[] reconfigured = new boolean[buckets.length];<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    int sizeNotMatchedCount = 0;<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    int insufficientCapacityCount = 0;<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    Iterator&lt;Map.Entry&lt;BlockCacheKey, BucketEntry&gt;&gt; iterator = map.entrySet().iterator();<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    while (iterator.hasNext()) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>      Map.Entry&lt;BlockCacheKey, BucketEntry&gt; entry = iterator.next();<a name="line.354"></a>
-<span class="sourceLineNo">355</span>      long foundOffset = entry.getValue().offset();<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      int foundLen = entry.getValue().getLength();<a name="line.356"></a>
-<span class="sourceLineNo">357</span>      int bucketSizeIndex = -1;<a name="line.357"></a>
-<span class="sourceLineNo">358</span>      for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>        if (foundLen &lt;= this.bucketSizes[i]) {<a name="line.359"></a>
-<span class="sourceLineNo">360</span>          bucketSizeIndex = i;<a name="line.360"></a>
-<span class="sourceLineNo">361</span>          break;<a name="line.361"></a>
-<span class="sourceLineNo">362</span>        }<a name="line.362"></a>
-<span class="sourceLineNo">363</span>      }<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      if (bucketSizeIndex == -1) {<a name="line.364"></a>
-<span class="sourceLineNo">365</span>        sizeNotMatchedCount++;<a name="line.365"></a>
-<span class="sourceLineNo">366</span>        iterator.remove();<a name="line.366"></a>
-<span class="sourceLineNo">367</span>        continue;<a name="line.367"></a>
-<span class="sourceLineNo">368</span>      }<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      int bucketNo = (int) (foundOffset / bucketCapacity);<a name="line.369"></a>
-<span class="sourceLineNo">370</span>      if (bucketNo &lt; 0 || bucketNo &gt;= buckets.length) {<a name="line.370"></a>
-<span class="sourceLineNo">371</span>        insufficientCapacityCount++;<a name="line.371"></a>
-<span class="sourceLineNo">372</span>        iterator.remove();<a name="line.372"></a>
-<span class="sourceLineNo">373</span>        continue;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>      }<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      Bucket b = buckets[bucketNo];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>      if (reconfigured[bucketNo]) {<a name="line.376"></a>
-<span class="sourceLineNo">377</span>        if (b.sizeIndex() != bucketSizeIndex) {<a name="line.377"></a>
-<span class="sourceLineNo">378</span>          throw new BucketAllocatorException("Inconsistent allocation in bucket map;");<a name="line.378"></a>
-<span class="sourceLineNo">379</span>        }<a name="line.379"></a>
-<span class="sourceLineNo">380</span>      } else {<a name="line.380"></a>
-<span class="sourceLineNo">381</span>        if (!b.isCompletelyFree()) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>          throw new BucketAllocatorException(<a name="line.382"></a>
-<span class="sourceLineNo">383</span>              "Reconfiguring bucket " + bucketNo + " but it's already allocated; corrupt data");<a name="line.383"></a>
-<span class="sourceLineNo">384</span>        }<a name="line.384"></a>
-<span class="sourceLineNo">385</span>        // Need to remove the bucket from whichever list it's currently in at<a name="line.385"></a>
-<span class="sourceLineNo">386</span>        // the moment...<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        BucketSizeInfo bsi = bucketSizeInfos[bucketSizeIndex];<a name="line.387"></a>
-<span class="sourceLineNo">388</span>        BucketSizeInfo oldbsi = bucketSizeInfos[b.sizeIndex()];<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        oldbsi.removeBucket(b);<a name="line.389"></a>
-<span class="sourceLineNo">390</span>        bsi.instantiateBucket(b);<a name="line.390"></a>
-<span class="sourceLineNo">391</span>        reconfigured[bucketNo] = true;<a name="line.391"></a>
-<span class="sourceLineNo">392</span>      }<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      realCacheSize.add(foundLen);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      buckets[bucketNo].addAllocation(foundOffset);<a name="line.394"></a>
-<span class="sourceLineNo">395</span>      usedSize += buckets[bucketNo].getItemAllocationSize();<a name="line.395"></a>
-<span class="sourceLineNo">396</span>      bucketSizeInfos[bucketSizeIndex].blockAllocated(b);<a name="line.396"></a>
-<span class="sourceLineNo">397</span>    }<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    if (sizeNotMatchedCount &gt; 0) {<a name="line.399"></a>
-<span class="sourceLineNo">400</span>      LOG.warn("There are " + sizeNotMatchedCount + " blocks which can't be rebuilt because " +<a name="line.400"></a>
-<span class="sourceLineNo">401</span>        "there is no matching bucket size for these blocks");<a name="line.401"></a>
-<span class="sourceLineNo">402</span>    }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>    if (insufficientCapacityCount &gt; 0) {<a name="line.403"></a>
-<span class="sourceLineNo">404</span>      LOG.warn("There are " + insufficientCapacityCount + " blocks which can't be rebuilt - "<a name="line.404"></a>
-<span class="sourceLineNo">405</span>        + "did you shrink the cache?");<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    }<a name="line.406"></a>
-<span class="sourceLineNo">407</span>  }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>  @Override<a name="line.409"></a>
-<span class="sourceLineNo">410</span>  public String toString() {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    StringBuilder sb = new StringBuilder(1024);<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      Bucket b = buckets[i];<a name="line.413"></a>
-<span class="sourceLineNo">414</span>      if (i &gt; 0) sb.append(", ");<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      sb.append("bucket.").append(i).append(": size=").append(b.getItemAllocationSize());<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      sb.append(", freeCount=").append(b.freeCount()).append(", used=").append(b.usedCount());<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    }<a name="line.417"></a>
-<span class="sourceLineNo">418</span>    return sb.toString();<a name="line.418"></a>
-<span class="sourceLineNo">419</span>  }<a name="line.419"></a>
-<span class="sourceLineNo">420</span><a name="line.420"></a>
-<span class="sourceLineNo">421</span>  public long getUsedSize() {<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    return this.usedSize;<a name="line.422"></a>
-<span class="sourceLineNo">423</span>  }<a name="line.423"></a>
-<span class="sourceLineNo">424</span><a name="line.424"></a>
-<span class="sourceLineNo">425</span>  public long getFreeSize() {<a name="line.425"></a>
-<span class="sourceLineNo">426</span>    return this.totalSize - getUsedSize();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>  }<a name="line.427"></a>
-<span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>  public long getTotalSize() {<a name="line.429"></a>
-<span class="sourceLineNo">430</span>    return this.totalSize;<a name="line.430"></a>
-<span class="sourceLineNo">431</span>  }<a name="line.431"></a>
-<span class="sourceLineNo">432</span><a name="line.432"></a>
-<span class="sourceLineNo">433</span>  /**<a name="line.433"></a>
-<span class="sourceLineNo">434</span>   * Allocate a block with specified size. Return the offset<a name="line.434"></a>
-<span class="sourceLineNo">435</span>   * @param blockSize size of block<a name="line.435"></a>
-<span class="sourceLineNo">436</span>   * @throws BucketAllocatorException<a name="line.436"></a>
-<span class="sourceLineNo">437</span>   * @throws CacheFullException<a name="line.437"></a>
-<span class="sourceLineNo">438</span>   * @return the offset in the IOEngine<a name="line.438"></a>
-<span class="sourceLineNo">439</span>   */<a name="line.439"></a>
-<span class="sourceLineNo">440</span>  public synchronized long allocateBlock(int blockSize) throws CacheFullException,<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      BucketAllocatorException {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    assert blockSize &gt; 0;<a name="line.442"></a>
-<span class="sourceLineNo">443</span>    BucketSizeInfo bsi = roundUpToBucketSizeInfo(blockSize);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    if (bsi == null) {<a name="line.444"></a>
-<span class="sourceLineNo">445</span>      throw new BucketAllocatorException("Allocation too big size=" + blockSize +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "; adjust BucketCache sizes " + BlockCacheFactory.BUCKET_CACHE_BUCKETS_KEY +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to accomodate if size seems reasonable and you want it cached.");<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    }<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    long offset = bsi.allocateBlock();<a name="line.449"></a>
-<span class="sourceLineNo">450</span><a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // Ask caller to free up space and try again!<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    if (offset &lt; 0)<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      throw new CacheFullException(blockSize, bsi.sizeIndex());<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    usedSize += bucketSizes[bsi.sizeIndex()];<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    return offset;<a name="line.455"></a>
-<span class="sourceLineNo">456</span>  }<a name="line.456"></a>
-<span class="sourceLineNo">457</span><a name="line.457"></a>
-<span class="sourceLineNo">458</span>  private Bucket grabGlobalCompletelyFreeBucket() {<a name="line.458"></a>
-<span class="sourceLineNo">459</span>    for (BucketSizeInfo bsi : bucketSizeInfos) {<a name="line.459"></a>
-<span class="sourceLineNo">460</span>      Bucket b = bsi.findAndRemoveCompletelyFreeBucket();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>      if (b != null) return b;<a name="line.461"></a>
-<span class="sourceLineNo">462</span>    }<a name="line.462"></a>
-<span class="sourceLineNo">463</span>    return null;<a name="line.463"></a>
-<span class="sourceLineNo">464</span>  }<a name="line.464"></a>
-<span class="sourceLineNo">465</span><a name="line.465"></a>
-<span class="sourceLineNo">466</span>  /**<a name="line.466"></a>
-<span class="sourceLineNo">467</span>   * Free a block with the offset<a name="line.467"></a>
-<span class="sourceLineNo">468</span>   * @param offset block's offset<a name="line.468"></a>
-<span class="sourceLineNo">469</span>   * @return size freed<a name="line.469"></a>
-<span class="sourceLineNo">470</span>   */<a name="line.470"></a>
-<span class="sourceLineNo">471</span>  public synchronized int freeBlock(long offset) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.473"></a>
-<span class="sourceLineNo">474</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.474"></a>
-<span class="sourceLineNo">475</span>    bucketSizeInfos[targetBucket.sizeIndex()].freeBlock(targetBucket, offset);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>    usedSize -= targetBucket.getItemAllocationSize();<a name="line.476"></a>
-<span class="sourceLineNo">477</span>    return targetBucket.getItemAllocationSize();<a name="line.477"></a>
-<span class="sourceLineNo">478</span>  }<a name="line.478"></a>
-<span class="sourceLineNo">479</span><a name="line.479"></a>
-<span class="sourceLineNo">480</span>  public int sizeIndexOfAllocation(long offset) {<a name="line.480"></a>
-<span class="sourceLineNo">481</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.481"></a>
-<span class="sourceLineNo">482</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    return targetBucket.sizeIndex();<a name="line.484"></a>
-<span class="sourceLineNo">485</span>  }<a name="line.485"></a>
-<span class="sourceLineNo">486</span><a name="line.486"></a>
-<span class="sourceLineNo">487</span>  public int sizeOfAllocation(long offset) {<a name="line.487"></a>
-<span class="sourceLineNo">488</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.488"></a>
-<span class="sourceLineNo">489</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.489"></a>
-<span class="sourceLineNo">490</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    return targetBucket.getItemAllocationSize();<a name="line.491"></a>
-<span class="sourceLineNo">492</span>  }<a name="line.492"></a>
-<span class="sourceLineNo">493</span><a name="line.493"></a>
-<span class="sourceLineNo">494</span>  static class IndexStatistics {<a name="line.494"></a>
-<span class="sourceLineNo">495</span>    private long freeCount, usedCount, itemSize, totalCount;<a name="line.495"></a>
-<span class="sourceLineNo">496</span><a name="line.496"></a>
-<span class="sourceLineNo">497</span>    public long freeCount() {<a name="line.497"></a>
-<span class="sourceLineNo">498</span>      return freeCount;<a name="line.498"></a>
-<span class="sourceLineNo">499</span>    }<a name="line.499"></a>
-<span class="sourceLineNo">500</span><a name="line.500"></a>
-<span class="sourceLineNo">501</span>    public long usedCount() {<a name="line.501"></a>
-<span class="sourceLineNo">502</span>      return usedCount;<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    }<a name="line.503"></a>
-<span class="sourceLineNo">504</span><a name="line.504"></a>
-<span class="sourceLineNo">505</span>    public long totalCount() {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      return totalCount;<a name="line.506"></a>
-<span class="sourceLineNo">507</span>    }<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>    public long freeBytes() {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>      return freeCount * itemSize;<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    }<a name="line.511"></a>
-<span class="sourceLineNo">512</span><a name="line.512"></a>
-<span class="sourceLineNo">513</span>    public long usedBytes() {<a name="line.513"></a>
-<span class="sourceLineNo">514</span>      return usedCount * itemSize;<a name="line.514"></a>
-<span class="sourceLineNo">515</span>    }<a name="line.515"></a>
-<span class="sourceLineNo">516</span><a name="line.516"></a>
-<span class="sourceLineNo">517</span>    public long totalBytes() {<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      return totalCount * itemSize;<a name="line.518"></a>
-<span class="sourceLineNo">519</span>    }<a name="line.519"></a>
-<span class="sourceLineNo">520</span><a name="line.520"></a>
-<span class="sourceLineNo">521</span>    public long itemSize() {<a name="line.521"></a>
-<span class="sourceLineNo">522</span>      return itemSize;<a name="line.522"></a>
-<span class="sourceLineNo">523</span>    }<a name="line.523"></a>
-<span class="sourceLineNo">524</span><a name="line.524"></a>
-<span class="sourceLineNo">525</span>    public IndexStatistics(long free, long used, long itemSize) {<a name="line.525"></a>
-<span class="sourceLineNo">526</span>      setTo(free, used, itemSize);<a name="line.526"></a>
-<span class="sourceLineNo">527</span>    }<a name="line.527"></a>
-<span class="sourceLineNo">528</span><a name="line.528"></a>
-<span class="sourceLineNo">529</span>    public IndexStatistics() {<a name="line.529"></a>
-<span class="sourceLineNo">530</span>      setTo(-1, -1, 0);<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    }<a name="line.531"></a>
-<span class="sourceLineNo">532</span><a name="line.532"></a>
-<span class="sourceLineNo">533</span>    public void setTo(long free, long used, long itemSize) {<a name="line.533"></a>
-<span class="sourceLineNo">534</span>      this.itemSize = itemSize;<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      this.freeCount = free;<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      this.usedCount = used;<a name="line.536"></a>
-<span class="sourceLineNo">537</span>      this.totalCount = free + used;<a name="line.537"></a>
-<span class="sourceLineNo">538</span>    }<a name="line.538"></a>
-<span class="sourceLineNo">539</span>  }<a name="line.539"></a>
-<span class="sourceLineNo">540</span><a name="line.540"></a>
-<span class="sourceLineNo">541</span>  public Bucket [] getBuckets() {<a name="line.541"></a>
-<span class="sourceLineNo">542</span>    return this.buckets;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>  }<a name="line.543"></a>
-<span class="sourceLineNo">544</span><a name="line.544"></a>
-<span class="sourceLineNo">545</span>  void logStatistics() {<a name="line.545"></a>
-<span class="sourceLineNo">546</span>    IndexStatistics total = new IndexStatistics();<a name="line.546"></a>
-<span class="sourceLineNo">547</span>    IndexStatistics[] stats = getIndexStatistics(total);<a name="line.547"></a>
-<span class="sourceLineNo">548</span>    LOG.info("Bucket allocator statistics follow:\n");<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    LOG.info("  Free bytes=" + total.freeBytes() + "+; used bytes="<a name="line.549"></a>
-<span class="sourceLineNo">550</span>        + total.usedBytes() + "; total bytes=" + total.totalBytes());<a name="line.550"></a>
-<span class="sourceLineNo">551</span>    for (IndexStatistics s : stats) {<a name="line.551"></a>
-<span class="sourceLineNo">552</span>      LOG.info("  Object size " + s.itemSize() + " used=" + s.usedCount()<a name="line.552"></a>
-<span class="sourceLineNo">553</span>          + "; free=" + s.freeCount() + "; total=" + s.totalCount());<a name="line.553"></a>
-<span class="sourceLineNo">554</span>    }<a name="line.554"></a>
-<span class="sourceLineNo">555</span>  }<a name="line.555"></a>
-<span class="sourceLineNo">556</span><a name="line.556"></a>
-<span class="sourceLineNo">557</span>  IndexStatistics[] getIndexStatistics(IndexStatistics grandTotal) {<a name="line.557"></a>
-<span class="sourceLineNo">558</span>    IndexStatistics[] stats = getIndexStatistics();<a name="line.558"></a>
-<span class="sourceLineNo">559</span>    long totalfree = 0, totalused = 0;<a name="line.559"></a>
-<span class="sourceLineNo">560</span>    for (IndexStatistics stat : stats) {<a name="line.560"></a>
-<span class="sourceLineNo">561</span>      totalfree += stat.freeBytes();<a name="line.561"></a>
-<span class="sourceLineNo">562</span>      totalused += stat.usedBytes();<a name="line.562"></a>
-<span class="sourceLineNo">563</span>    }<a name="line.563"></a>
-<span class="sourceLineNo">564</span>    grandTotal.setTo(totalfree, totalused, 1);<a name="line.564"></a>
-<span class="sourceLineNo">565</span>    return stats;<a name="line.565"></a>
-<span class="sourceLineNo">566</span>  }<a name="line.566"></a>
-<span class="sourceLineNo">567</span><a name="line.567"></a>
-<span class="sourceLineNo">568</span>  IndexStatistics[] getIndexStatistics() {<a name="line.568"></a>
-<span class="sourceLineNo">569</span>    IndexStatistics[] stats = new IndexStatistics[bucketSizes.length];<a name="line.569"></a>
-<span class="sourceLineNo">570</span>    for (int i = 0; i &lt; stats.length; ++i)<a name="line.570"></a>
-<span class="sourceLineNo">571</span>      stats[i] = bucketSizeInfos[i].statistics();<a name="line.571"></a>
-<span class="sourceLineNo">572</span>    return stats;<a name="line.572"></a>
-<span class="sourceLineNo">573</span>  }<a name="line.573"></a>
-<span class="sourceLineNo">574</span><a name="line.574"></a>
-<span class="sourceLineNo">575</span>  public long freeBlock(long freeList[]) {<a name="line.575"></a>
-<span class="sourceLineNo">576</span>    long sz = 0;<a name="line.576"></a>
-<span class="sourceLineNo">577</span>    for (int i = 0; i &lt; freeList.length; ++i)<a name="line.577"></a>
-<span class="sourceLineNo">578</span>      sz += freeBlock(freeList[i]);<a name="line.578"></a>
-<span class="sourceLineNo">579</span>    return sz;<a name="line.579"></a>
-<span class="sourceLineNo">580</span>  }<a name="line.580"></a>
-<span class="sourceLineNo">581</span><a name="line.581"></a>
-<span class="sourceLineNo">582</span>  public int getBucketIndex(long offset) {<a name="line.582"></a>
-<span class="sourceLineNo">583</span>    return (int) (offset / bucketCapacity);<a name="line.583"></a>
-<span class="sourceLineNo">584</span>  }<a name="line.584"></a>
-<span class="sourceLineNo">585</span><a name="line.585"></a>
-<span class="sourceLineNo">586</span>  /**<a name="line.586"></a>
-<span class="sourceLineNo">587</span>   * Returns a set of indices of the buckets that are least filled<a name="line.587"></a>
-<span class="sourceLineNo">588</span>   * excluding the offsets, we also the fully free buckets for the<a name="line.588"></a>
-<span class="sourceLineNo">589</span>   * BucketSizes where everything is empty and they only have one<a name="line.589"></a>
-<span class="sourceLineNo">590</span>   * completely free bucket as a reserved<a name="line.590"></a>
-<span class="sourceLineNo">591</span>   *<a name="line.591"></a>
-<span class="sourceLineNo">592</span>   * @param excludedBuckets the buckets that need to be excluded due to<a name="line.592"></a>
-<span class="sourceLineNo">593</span>   *                        currently being in used<a name="line.593"></a>
-<span class="sourceLineNo">594</span>   * @param bucketCount     max Number of buckets to return<a name="line.594"></a>
-<span class="sourceLineNo">595</span>   * @return set of bucket indices which could be used for eviction<a name="line.595"></a>
-<span class="sourceLineNo">596</span>   */<a name="line.596"></a>
-<span class="sourceLineNo">597</span>  public Set&lt;Integer&gt; getLeastFilledBuckets(Set&lt;Integer&gt; excludedBuckets,<a name="line.597"></a>
-<span class="sourceLineNo">598</span>                                            int bucketCount) {<a name="line.598"></a>
-<span class="sourceLineNo">599</span>    Queue&lt;Integer&gt; queue = MinMaxPriorityQueue.&lt;Integer&gt;orderedBy(<a name="line.599"></a>
-<span class="sourceLineNo">600</span>        new Comparator&lt;Integer&gt;() {<a name="line.600"></a>
-<span class="sourceLineNo">601</span>          @Override<a name="line.601"></a>
-<span class="sourceLineNo">602</span>          public int compare(Integer left, Integer right) {<a name="line.602"></a>
-<span class="sourceLineNo">603</span>            // We will always get instantiated buckets<a name="line.603"></a>
-<span class="sourceLineNo">604</span>            return Float.compare(<a name="line.604"></a>
-<span class="sourceLineNo">605</span>                ((float) buckets[left].usedCount) / buckets[left].itemCount,<a name="line.605"></a>
-<span class="sourceLineNo">606</span>                ((float) buckets[right].usedCount) / buckets[right].itemCount);<a name="line.606"></a>
-<span class="sourceLineNo">607</span>          }<a name="line.607"></a>
-<span class="sourceLineNo">608</span>        }).maximumSize(bucketCount).create();<a name="line.608"></a>
-<span class="sourceLineNo">609</span><a name="line.609"></a>
-<span class="sourceLineNo">610</span>    for (int i = 0; i &lt; buckets.length; i ++ ) {<a name="line.610"></a>
-<span class="sourceLineNo">611</span>      if (!excludedBuckets.contains(i) &amp;&amp; !buckets[i].isUninstantiated() &amp;&amp;<a name="line.611"></a>
-<span class="sourceLineNo">612</span>          // Avoid the buckets that are the only buckets for a sizeIndex<a name="line.612"></a>
-<span class="sourceLineNo">613</span>          bucketSizeInfos[buckets[i].sizeIndex()].bucketList.size() != 1) {<a name="line.613"></a>
-<span class="sourceLineNo">614</span>        queue.add(i);<a name="line.614"></a>
-<span class="sourceLineNo">615</span>      }<a name="line.615"></a>
-<span class="sourceLineNo">616</span>    }<a name="line.616"></a>
-<span class="sourceLineNo">617</span><a name="line.617"></a>
-<span class="sourceLineNo">618</span>    Set&lt;Integer&gt; result = new HashSet&lt;&gt;(bucketCount);<a name="line.618"></a>
-<span class="sourceLineNo">619</span>    result.addAll(queue);<a name="line.619"></a>
-<span class="sourceLineNo">620</span><a name="line.620"></a>
-<span class="sourceLineNo">621</span>    return result;<a name="line.621"></a>
-<span class="sourceLineNo">622</span>  }<a name="line.622"></a>
-<span class="sourceLineNo">623</span>}<a name="line.623"></a>
+<span class="sourceLineNo">272</span>  // The real block size in hfile maybe a little larger than the size we configured ,<a name="line.272"></a>
+<span class="sourceLineNo">273</span>  // so we need add extra 1024 bytes for fit.<a name="line.273"></a>
+<span class="sourceLineNo">274</span>  // TODO Support the view of block size distribution statistics<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  private static final int DEFAULT_BUCKET_SIZES[] = { 4 * 1024 + 1024, 8 * 1024 + 1024,<a name="line.275"></a>
+<span class="sourceLineNo">276</span>      16 * 1024 + 1024, 32 * 1024 + 1024, 40 * 1024 + 1024, 48 * 1024 + 1024,<a name="line.276"></a>
+<span class="sourceLineNo">277</span>      56 * 1024 + 1024, 64 * 1024 + 1024, 96 * 1024 + 1024, 128 * 1024 + 1024,<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      192 * 1024 + 1024, 256 * 1024 + 1024, 384 * 1024 + 1024,<a name="line.278"></a>
+<span class="sourceLineNo">279</span>      512 * 1024 + 1024 };<a name="line.279"></a>
+<span class="sourceLineNo">280</span><a name="line.280"></a>
+<span class="sourceLineNo">281</span>  /**<a name="line.281"></a>
+<span class="sourceLineNo">282</span>   * Round up the given block size to bucket size, and get the corresponding<a name="line.282"></a>
+<span class="sourceLineNo">283</span>   * BucketSizeInfo<a name="line.283"></a>
+<span class="sourceLineNo">284</span>   */<a name="line.284"></a>
+<span class="sourceLineNo">285</span>  public BucketSizeInfo roundUpToBucketSizeInfo(int blockSize) {<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    for (int i = 0; i &lt; bucketSizes.length; ++i)<a name="line.286"></a>
+<span class="sourceLineNo">287</span>      if (blockSize &lt;= bucketSizes[i])<a name="line.287"></a>
+<span class="sourceLineNo">288</span>        return bucketSizeInfos[i];<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    return null;<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>  /**<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   * So, what is the minimum amount of items we'll tolerate in a single bucket?<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
+<span class="sourceLineNo">295</span>  static public final int FEWEST_ITEMS_IN_BUCKET = 4;<a name="line.295"></a>
+<span class="sourceLineNo">296</span><a name="line.296"></a>
+<span class="sourceLineNo">297</span>  private final int[] bucketSizes;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>  private final int bigItemSize;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>  // The capacity size for each bucket<a name="line.299"></a>
+<span class="sourceLineNo">300</span>  private final long bucketCapacity;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>  private Bucket[] buckets;<a name="line.301"></a>
+<span class="sourceLineNo">302</span>  private BucketSizeInfo[] bucketSizeInfos;<a name="line.302"></a>
+<span class="sourceLineNo">303</span>  private final long totalSize;<a name="line.303"></a>
+<span class="sourceLineNo">304</span>  private transient long usedSize = 0;<a name="line.304"></a>
+<span class="sourceLineNo">305</span><a name="line.305"></a>
+<span class="sourceLineNo">306</span>  BucketAllocator(long availableSpace, int[] bucketSizes)<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      throws BucketAllocatorException {<a name="line.307"></a>
+<span class="sourceLineNo">308</span>    this.bucketSizes = bucketSizes == null ? DEFAULT_BUCKET_SIZES : bucketSizes;<a name="line.308"></a>
+<span class="sourceLineNo">309</span>    Arrays.sort(this.bucketSizes);<a name="line.309"></a>
+<span class="sourceLineNo">310</span>    this.bigItemSize = Ints.max(this.bucketSizes);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    this.bucketCapacity = FEWEST_ITEMS_IN_BUCKET * (long) bigItemSize;<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    buckets = new Bucket[(int) (availableSpace / bucketCapacity)];<a name="line.312"></a>
+<span class="sourceLineNo">313</span>    if (buckets.length &lt; this.bucketSizes.length)<a name="line.313"></a>
+<span class="sourceLineNo">314</span>      throw new BucketAllocatorException("Bucket allocator size too small (" + buckets.length +<a name="line.314"></a>
+<span class="sourceLineNo">315</span>        "); must have room for at least " + this.bucketSizes.length + " buckets");<a name="line.315"></a>
+<span class="sourceLineNo">316</span>    bucketSizeInfos = new BucketSizeInfo[this.bucketSizes.length];<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>      bucketSizeInfos[i] = new BucketSizeInfo(i);<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    }<a name="line.319"></a>
+<span class="sourceLineNo">320</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.320"></a>
+<span class="sourceLineNo">321</span>      buckets[i] = new Bucket(bucketCapacity * i);<a name="line.321"></a>
+<span class="sourceLineNo">322</span>      bucketSizeInfos[i &lt; this.bucketSizes.length ? i : this.bucketSizes.length - 1]<a name="line.322"></a>
+<span class="sourceLineNo">323</span>          .instantiateBucket(buckets[i]);<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    }<a name="line.324"></a>
+<span class="sourceLineNo">325</span>    this.totalSize = ((long) buckets.length) * bucketCapacity;<a name="line.325"></a>
+<span class="sourceLineNo">326</span>    if (LOG.isInfoEnabled()) {<a name="line.326"></a>
+<span class="sourceLineNo">327</span>      LOG.info("Cache totalSize=" + this.totalSize + ", buckets=" + this.buckets.length +<a name="line.327"></a>
+<span class="sourceLineNo">328</span>        ", bucket capacity=" + this.bucketCapacity +<a name="line.328"></a>
+<span class="sourceLineNo">329</span>        "=(" + FEWEST_ITEMS_IN_BUCKET + "*" + this.bigItemSize + ")=" +<a name="line.329"></a>
+<span class="sourceLineNo">330</span>        "(FEWEST_ITEMS_IN_BUCKET*(largest configured bucketcache size))");<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 name="line.333"></a>
+<span class="sourceLineNo">334</span>  /**<a name="line.334"></a>
+<span class="sourceLineNo">335</span>   * Rebuild the allocator's data structures from a persisted map.<a name="line.335"></a>
+<span class="sourceLineNo">336</span>   * @param availableSpace capacity of cache<a name="line.336"></a>
+<span class="sourceLineNo">337</span>   * @param map A map stores the block key and BucketEntry(block's meta data<a name="line.337"></a>
+<span class="sourceLineNo">338</span>   *          like offset, length)<a name="line.338"></a>
+<span class="sourceLineNo">339</span>   * @param realCacheSize cached data size statistics for bucket cache<a name="line.339"></a>
+<span class="sourceLineNo">340</span>   * @throws BucketAllocatorException<a name="line.340"></a>
+<span class="sourceLineNo">341</span>   */<a name="line.341"></a>
+<span class="sourceLineNo">342</span>  BucketAllocator(long availableSpace, int[] bucketSizes, Map&lt;BlockCacheKey, BucketEntry&gt; map,<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      LongAdder realCacheSize) throws BucketAllocatorException {<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    this(availableSpace, bucketSizes);<a name="line.344"></a>
+<span class="sourceLineNo">345</span><a name="line.345"></a>
+<span class="sourceLineNo">346</span>    // each bucket has an offset, sizeindex. probably the buckets are too big<a name="line.346"></a>
+<span class="sourceLineNo">347</span>    // in our default state. so what we do is reconfigure them according to what<a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // we've found. we can only reconfigure each bucket once; if more than once,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // we know there's a bug, so we just log the info, throw, and start again...<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    boolean[] reconfigured = new boolean[buckets.length];<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    int sizeNotMatchedCount = 0;<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    int insufficientCapacityCount = 0;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    Iterator&lt;Map.Entry&lt;BlockCacheKey, BucketEntry&gt;&gt; iterator = map.entrySet().iterator();<a name="line.353"></a>
+<span class="sourceLineNo">354</span>    while (iterator.hasNext()) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      Map.Entry&lt;BlockCacheKey, BucketEntry&gt; entry = iterator.next();<a name="line.355"></a>
+<span class="sourceLineNo">356</span>      long foundOffset = entry.getValue().offset();<a name="line.356"></a>
+<span class="sourceLineNo">357</span>      int foundLen = entry.getValue().getLength();<a name="line.357"></a>
+<span class="sourceLineNo">358</span>      int bucketSizeIndex = -1;<a name="line.358"></a>
+<span class="sourceLineNo">359</span>      for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.359"></a>
+<span class="sourceLineNo">360</span>        if (foundLen &lt;= this.bucketSizes[i]) {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>          bucketSizeIndex = i;<a name="line.361"></a>
+<span class="sourceLineNo">362</span>          break;<a name="line.362"></a>
+<span class="sourceLineNo">363</span>        }<a name="line.363"></a>
+<span class="sourceLineNo">364</span>      }<a name="line.364"></a>
+<span class="sourceLineNo">365</span>      if (bucketSizeIndex == -1) {<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        sizeNotMatchedCount++;<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        iterator.remove();<a name="line.367"></a>
+<span class="sourceLineNo">368</span>        continue;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>      }<a name="line.369"></a>
+<span class="sourceLineNo">370</span>      int bucketNo = (int) (foundOffset / bucketCapacity);<a name="line.370"></a>
+<span class="sourceLineNo">371</span>      if (bucketNo &lt; 0 || bucketNo &gt;= buckets.length) {<a name="line.371"></a>
+<span class="sourceLineNo">372</span>        insufficientCapacityCount++;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>        iterator.remove();<a name="line.373"></a>
+<span class="sourceLineNo">374</span>        continue;<a name="line.374"></a>
+<span class="sourceLineNo">375</span>      }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>      Bucket b = buckets[bucketNo];<a name="line.376"></a>
+<span class="sourceLineNo">377</span>      if (reconfigured[bucketNo]) {<a name="line.377"></a>
+<span class="sourceLineNo">378</span>        if (b.sizeIndex() != bucketSizeIndex) {<a name="line.378"></a>
+<span class="sourceLineNo">379</span>          throw new BucketAllocatorException("Inconsistent allocation in bucket map;");<a name="line.379"></a>
+<span class="sourceLineNo">380</span>        }<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      } else {<a name="line.381"></a>
+<span class="sourceLineNo">382</span>        if (!b.isCompletelyFree()) {<a name="line.382"></a>
+<span class="sourceLineNo">383</span>          throw new BucketAllocatorException(<a name="line.383"></a>
+<span class="sourceLineNo">384</span>              "Reconfiguring bucket " + bucketNo + " but it's already allocated; corrupt data");<a name="line.384"></a>
+<span class="sourceLineNo">385</span>        }<a name="line.385"></a>
+<span class="sourceLineNo">386</span>        // Need to remove the bucket from whichever list it's currently in at<a name="line.386"></a>
+<span class="sourceLineNo">387</span>        // the moment...<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        BucketSizeInfo bsi = bucketSizeInfos[bucketSizeIndex];<a name="line.388"></a>
+<span class="sourceLineNo">389</span>        BucketSizeInfo oldbsi = bucketSizeInfos[b.sizeIndex()];<a name="line.389"></a>
+<span class="sourceLineNo">390</span>        oldbsi.removeBucket(b);<a name="line.390"></a>
+<span class="sourceLineNo">391</span>        bsi.instantiateBucket(b);<a name="line.391"></a>
+<span class="sourceLineNo">392</span>        reconfigured[bucketNo] = true;<a name="line.392"></a>
+<span class="sourceLineNo">393</span>      }<a name="line.393"></a>
+<span class="sourceLineNo">394</span>      realCacheSize.add(foundLen);<a name="line.394"></a>
+<span class="sourceLineNo">395</span>      buckets[bucketNo].addAllocation(foundOffset);<a name="line.395"></a>
+<span class="sourceLineNo">396</span>      usedSize += buckets[bucketNo].getItemAllocationSize();<a name="line.396"></a>
+<span class="sourceLineNo">397</span>      bucketSizeInfos[bucketSizeIndex].blockAllocated(b);<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    }<a name="line.398"></a>
+<span class="sourceLineNo">399</span><a name="line.399"></a>
+<span class="sourceLineNo">400</span>    if (sizeNotMatchedCount &gt; 0) {<a name="line.400"></a>
+<span class="sourceLineNo">401</span>      LOG.warn("There are " + sizeNotMatchedCount + " blocks which can't be rebuilt because " +<a name="line.401"></a>
+<span class="sourceLineNo">402</span>        "there is no matching bucket size for these blocks");<a name="line.402"></a>
+<span class="sourceLineNo">403</span>    }<a name="line.403"></a>
+<span class="sourceLineNo">404</span>    if (insufficientCapacityCount &gt; 0) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>      LOG.warn("There are " + insufficientCapacityCount + " blocks which can't be rebuilt - "<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        + "did you shrink the cache?");<a name="line.406"></a>
+<span class="sourceLineNo">407</span>    }<a name="line.407"></a>
+<span class="sourceLineNo">408</span>  }<a name="line.408"></a>
+<span class="sourceLineNo">409</span><a name="line.409"></a>
+<span class="sourceLineNo">410</span>  @Override<a name="line.410"></a>
+<span class="sourceLineNo">411</span>  public String toString() {<a name="line.411"></a>
+<span class="sourceLineNo">412</span>    StringBuilder sb = new StringBuilder(1024);<a name="line.412"></a>
+<span class="sourceLineNo">413</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      Bucket b = buckets[i];<a name="line.414"></a>
+<span class="sourceLineNo">415</span>      if (i &gt; 0) sb.append(", ");<a name="line.415"></a>
+<span class="sourceLineNo">416</span>      sb.append("bucket.").append(i).append(": size=").append(b.getItemAllocationSize());<a name="line.416"></a>
+<span class="sourceLineNo">417</span>      sb.append(", freeCount=").append(b.freeCount()).append(", used=").append(b.usedCount());<a name="line.417"></a>
+<span class="sourceLineNo">418</span>    }<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    return sb.toString();<a name="line.419"></a>
+<span class="sourceLineNo">420</span>  }<a name="line.420"></a>
+<span class="sourceLineNo">421</span><a name="line.421"></a>
+<span class="sourceLineNo">422</span>  public long getUsedSize() {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    return this.usedSize;<a name="line.423"></a>
+<span class="sourceLineNo">424</span>  }<a name="line.424"></a>
+<span class="sourceLineNo">425</span><a name="line.425"></a>
+<span class="sourceLineNo">426</span>  public long getFreeSize() {<a name="line.426"></a>
+<span class="sourceLineNo">427</span>    return this.totalSize - getUsedSize();<a name="line.427"></a>
+<span class="sourceLineNo">428</span>  }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>  public long getTotalSize() {<a name="line.430"></a>
+<span class="sourceLineNo">431</span>    return this.totalSize;<a name="line.431"></a>
+<span class="sourceLineNo">432</span>  }<a name="line.432"></a>
+<span class="sourceLineNo">433</span><a name="line.433"></a>
+<span class="sourceLineNo">434</span>  /**<a name="line.434"></a>
+<span class="sourceLineNo">435</span>   * Allocate a block with specified size. Return the offset<a name="line.435"></a>
+<span class="sourceLineNo">436</span>   * @param blockSize size of block<a name="line.436"></a>
+<span class="sourceLineNo">437</span>   * @throws BucketAllocatorException<a name="line.437"></a>
+<span class="sourceLineNo">438</span>   * @throws CacheFullException<a name="line.438"></a>
+<span class="sourceLineNo">439</span>   * @return the offset in the IOEngine<a name="line.439"></a>
+<span class="sourceLineNo">440</span>   */<a name="line.440"></a>
+<span class="sourceLineNo">441</span>  public synchronized long allocateBlock(int blockSize) throws CacheFullException,<a name="line.441"></a>
+<span class="sourceLineNo">442</span>      BucketAllocatorException {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>    assert blockSize &gt; 0;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>    BucketSizeInfo bsi = roundUpToBucketSizeInfo(blockSize);<a name="line.444"></a>
+<span class="sourceLineNo">445</span>    if (bsi == null) {<a name="line.445"></a>
+<span class="sourceLineNo">446</span>      throw new BucketAllocatorException("Allocation too big size=" + blockSize +<a name="line.446"></a>
+<span class="sourceLineNo">447</span>        "; adjust BucketCache sizes " + BlockCacheFactory.BUCKET_CACHE_BUCKETS_KEY +<a name="line.447"></a>
+<span class="sourceLineNo">448</span>        " to accomodate if size seems reasonable and you want it cached.");<a name="line.448"></a>
+<span class="sourceLineNo">449</span>    }<a name="line.449"></a>
+<span class="sourceLineNo">450</span>    long offset = bsi.allocateBlock();<a name="line.450"></a>
+<span class="sourceLineNo">451</span><a name="line.451"></a>
+<span class="sourceLineNo">452</span>    // Ask caller to free up space and try again!<a name="line.452"></a>
+<span class="sourceLineNo">453</span>    if (offset &lt; 0)<a name="line.453"></a>
+<span class="sourceLineNo">454</span>      throw new CacheFullException(blockSize, bsi.sizeIndex());<a name="line.454"></a>
+<span class="sourceLineNo">455</span>    usedSize += bucketSizes[bsi.sizeIndex()];<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    return offset;<a name="line.456"></a>
+<span class="sourceLineNo">457</span>  }<a name="line.457"></a>
+<span class="sourceLineNo">458</span><a name="line.458"></a>
+<span class="sourceLineNo">459</span>  private Bucket grabGlobalCompletelyFreeBucket() {<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    for (BucketSizeInfo bsi : bucketSizeInfos) {<a name="line.460"></a>
+<span class="sourceLineNo">461</span>      Bucket b = bsi.findAndRemoveCompletelyFreeBucket();<a name="line.461"></a>
+<span class="sourceLineNo">462</span>      if (b != null) return b;<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    }<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    return null;<a name="line.464"></a>
+<span class="sourceLineNo">465</span>  }<a name="line.465"></a>
+<span class="sourceLineNo">466</span><a name="line.466"></a>
+<span class="sourceLineNo">467</span>  /**<a name="line.467"></a>
+<span class="sourceLineNo">468</span>   * Free a block with the offset<a name="line.468"></a>
+<span class="sourceLineNo">469</span>   * @param offset block's offset<a name="line.469"></a>
+<span class="sourceLineNo">470</span>   * @return size freed<a name="line.470"></a>
+<span class="sourceLineNo">471</span>   */<a name="line.471"></a>
+<span class="sourceLineNo">472</span>  public synchronized int freeBlock(long offset) {<a name="line.472"></a>
+<span class="sourceLineNo">473</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.473"></a>
+<span class="sourceLineNo">474</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.474"></a>
+<span class="sourceLineNo">475</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.475"></a>
+<span class="sourceLineNo">476</span>    bucketSizeInfos[targetBucket.sizeIndex()].freeBlock(targetBucket, offset);<a name="line.476"></a>
+<span class="sourceLineNo">477</span>    usedSize -= targetBucket.getItemAllocationSize();<a name="line.477"></a>
+<span class="sourceLineNo">478</span>    return targetBucket.getItemAllocationSize();<a name="line.478"></a>
+<span class="sourceLineNo">479</span>  }<a name="line.479"></a>
+<span class="sourceLineNo">480</span><a name="line.480"></a>
+<span class="sourceLineNo">481</span>  public int sizeIndexOfAllocation(long offset) {<a name="line.481"></a>
+<span class="sourceLineNo">482</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.482"></a>
+<span class="sourceLineNo">483</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.483"></a>
+<span class="sourceLineNo">484</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.484"></a>
+<span class="sourceLineNo">485</span>    return targetBucket.sizeIndex();<a name="line.485"></a>
+<span class="sourceLineNo">486</span>  }<a name="line.486"></a>
+<span class="sourceLineNo">487</span><a name="line.487"></a>
+<span class="sourceLineNo">488</span>  public int sizeOfAllocation(long offset) {<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.489"></a>
+<span class="sourceLineNo">490</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.490"></a>
+<span class="sourceLineNo">491</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.491"></a>
+<span class="sourceLineNo">492</span>    return targetBucket.getItemAllocationSize();<a name="line.492"></a>
+<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
+<span class="sourceLineNo">494</span><a name="line.494"></a>
+<span class="sourceLineNo">495</span>  static class IndexStatistics {<a name="line.495"></a>
+<span class="sourceLineNo">496</span>    private long freeCount, usedCount, itemSize, totalCount;<a name="line.496"></a>
+<span class="sourceLineNo">497</span><a name="line.497"></a>
+<span class="sourceLineNo">498</span>    public long freeCount() {<a name="line.498"></a>
+<span class="sourceLineNo">499</span>      return freeCount;<a name="line.499"></a>
+<span class="sourceLineNo">500</span>    }<a name="line.500"></a>
+<span class="sourceLineNo">501</span><a name="line.501"></a>
+<span class="sourceLineNo">502</span>    public long usedCount() {<a name="line.502"></a>
+<span class="sourceLineNo">503</span>      return usedCount;<a name="line.503"></a>
+<span class="sourceLineNo">504</span>    }<a name="line.504"></a>
+<span class="sourceLineNo">505</span><a name="line.505"></a>
+<span class="sourceLineNo">506</span>    public long totalCount() {<a name="line.506"></a>
+<span class="sourceLineNo">507</span>      return totalCount;<a name="line.507"></a>
+<span class="sourceLineNo">508</span>    }<a name="line.508"></a>
+<span class="sourceLineNo">509</span><a name="line.509"></a>
+<span class="sourceLineNo">510</span>    public long freeBytes() {<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      return freeCount * itemSize;<a name="line.511"></a>
+<span class="sourceLineNo">512</span>    }<a name="line.512"></a>
+<span class="sourceLineNo">513</span><a name="line.513"></a>
+<span class="sourceLineNo">514</span>    public long usedBytes() {<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      return usedCount * itemSize;<a name="line.515"></a>
+<span class="sourceLineNo">516</span>    }<a name="line.516"></a>
+<span class="sourceLineNo">517</span><a name="line.517"></a>
+<span class="sourceLineNo">518</span>    public long totalBytes() {<a name="line.518"></a>
+<span class="sourceLineNo">519</span>      return totalCount * itemSize;<a name="line.519"></a>
+<span class="sourceLineNo">520</span>    }<a name="line.520"></a>
+<span class="sourceLineNo">521</span><a name="line.521"></a>
+<span class="sourceLineNo">522</span>    public long itemSize() {<a name="line.522"></a>
+<span class="sourceLineNo">523</span>      return itemSize;<a name="line.523"></a>
+<span class="sourceLineNo">524</span>    }<a name="line.524"></a>
+<span class="sourceLineNo">525</span><a name="line.525"></a>
+<span class="sourceLineNo">526</span>    public IndexStatistics(long free, long used, long itemSize) {<a name="line.526"></a>
+<span class="sourceLineNo">527</span>      setTo(free, used, itemSize);<a name="line.527"></a>
+<span class="sourceLineNo">528</span>    }<a name="line.528"></a>
+<span class="sourceLineNo">529</span><a name="line.529"></a>
+<span class="sourceLineNo">530</span>    public IndexStatistics() {<a name="line.530"></a>
+<span class="sourceLineNo">531</span>      setTo(-1, -1, 0);<a name="line.531"></a>
+<span class="sourceLineNo">532</span>    }<a name="line.532"></a>
+<span class="sourceLineNo">533</span><a name="line.533"></a>
+<span class="sourceLineNo">534</span>    public void setTo(long free, long used, long itemSize) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>      this.itemSize = itemSize;<a name="line.535"></a>
+<span class="sourceLineNo">536</span>      this.freeCount = free;<a name="line.536"></a>
+<span class="sourceLineNo">537</span>      this.usedCount = used;<a name="line.537"></a>
+<span class="sourceLineNo">538</span>      this.totalCount = free + used;<a name="line.538"></a>
+<span class="sourceLineNo">539</span>    }<a name="line.539"></a>
+<span class="sourceLineNo">540</span>  }<a name="line.540"></a>
+<span class="sourceLineNo">541</span><a name="line.541"></a>
+<span class="sourceLineNo">542</span>  public Bucket [] getBuckets() {<a name="line.542"></a>
+<span class="sourceLineNo">543</span>    return this.buckets;<a name="line.543"></a>
+<span class="sourceLineNo">544</span>  }<a name="line.544"></a>
+<span class="sourceLineNo">545</span><a name="line.545"></a>
+<span class="sourceLineNo">546</span>  void logStatistics() {<a name="line.546"></a>
+<span class="sourceLineNo">547</span>    IndexStatistics total = new IndexStatistics();<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    IndexStatistics[] stats = getIndexStatistics(total);<a name="line.548"></a>
+<span class="sourceLineNo">549</span>    LOG.info("Bucket allocator statistics follow:\n");<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    LOG.info("  Free bytes=" + total.freeBytes() + "+; used bytes="<a name="line.550"></a>
+<span class="sourceLineNo">551</span>        + total.usedBytes() + "; total bytes=" + total.totalBytes());<a name="line.551"></a>
+<span class="sourceLineNo">552</span>    for (IndexStatistics s : stats) {<a name="line.552"></a>
+<span class="sourceLineNo">553</span>      LOG.info("  Object size " + s.itemSize() + " used=" + s.usedCount()<a name="line.553"></a>
+<span class="sourceLineNo">554</span>          + "; free=" + s.freeCount() + "; total=" + s.totalCount());<a name="line.554"></a>
+<span class="sourceLineNo">555</span>    }<a name="line.555"></a>
+<span class="sourceLineNo">556</span>  }<a name="line.556"></a>
+<span class="sourceLineNo">557</span><a name="line.557"></a>
+<span class="sourceLineNo">558</span>  IndexStatistics[] getIndexStatistics(IndexStatistics grandTotal) {<a name="line.558"></a>
+<span class="sourceLineNo">559</span>    IndexStatistics[] stats = getIndexStatistics();<a name="line.559"></a>
+<span class="sourceLineNo">560</span>    long totalfree = 0, totalused = 0;<a name="line.560"></a>
+<span class="sourceLineNo">561</span>    for (IndexStatistics stat : stats) {<a name="line.561"></a>
+<span class="sourceLineNo">562</span>      totalfree += stat.freeBytes();<a name="line.562"></a>
+<span class="sourceLineNo">563</span>      totalused += stat.usedBytes();<a name="line.563"></a>
+<span class="sourceLineNo">564</span>    }<a name="line.564"></a>
+<span class="sourceLineNo">565</span>    grandTotal.setTo(totalfree, totalused, 1);<a name="line.565"></a>
+<span class="sourceLineNo">566</span>    return stats;<a name="line.566"></a>
+<span class="sourceLineNo">567</span>  }<a name="line.567"></a>
+<span class="sourceLineNo">568</span><a name="line.568"></a>
+<span class="sourceLineNo">569</span>  IndexStatistics[] getIndexStatistics() {<a name="line.569"></a>
+<span class="sourceLineNo">570</span>    IndexStatistics[] stats = new IndexStatistics[bucketSizes.length];<a name="line.570"></a>
+<span class="sourceLineNo">571</span>    for (int i = 0; i &lt; stats.length; ++i)<a name="line.571"></a>
+<span class="sourceLineNo">572</span>      stats[i] = bucketSizeInfos[i].statistics();<a name="line.572"></a>
+<span class="sourceLineNo">573</span>    return stats;<a name="line.573"></a>
+<span class="sourceLineNo">574</span>  }<a name="line.574"></a>
+<span class="sourceLineNo">575</span><a name="line.575"></a>
+<span class="sourceLineNo">576</span>  public long freeBlock(long freeList[]) {<a name="line.576"></a>
+<span class="sourceLineNo">577</span>    long sz = 0;<a name="line.577"></a>
+<span class="sourceLineNo">578</span>    for (int i = 0; i &lt; freeList.length; ++i)<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      sz += freeBlock(freeList[i]);<a name="line.579"></a>
+<span class="sourceLineNo">580</span>    return sz;<a name="line.580"></a>
+<span class="sourceLineNo">581</span>  }<a name="line.581"></a>
+<span class="sourceLineNo">582</span><a name="line.582"></a>
+<span class="sourceLineNo">583</span>  public int getBucketIndex(long offset) {<a name="line.583"></a>
+<span class="sourceLineNo">584</span>    return (int) (offset / bucketCapacity);<a name="line.584"></a>
+<span class="sourceLineNo">585</span>  }<a name="line.585"></a>
+<span class="sourceLineNo">586</span><a name="line.586"></a>
+<span class="sourceLineNo">587</span>  /**<a name="line.587"></a>
+<span class="sourceLineNo">588</span>   * Returns a set of indices of the buckets that are least filled<a name="line.588"></a>
+<span class="sourceLineNo">589</span>   * excluding the offsets, we also the fully free buckets for the<a name="line.589"></a>
+<span class="sourceLineNo">590</span>   * BucketSizes where everything is empty and they only have one<a name="line.590"></a>
+<span class="sourceLineNo">591</span>   * completely free bucket as a reserved<a name="line.591"></a>
+<span class="sourceLineNo">592</span>   *<a name="line.592"></a>
+<span class="sourceLineNo">593</span>   * @param excludedBuckets the buckets that need to be excluded due to<a name="line.593"></a>
+<span class="sourceLineNo">594</span>   *                        currently being in used<a name="line.594"></a>
+<span class="sourceLineNo">595</span>   * @param bucketCount     max Number of buckets to return<a name="line.595"></a>
+<span class="sourceLineNo">596</span>   * @return set of bucket indices which could be used for eviction<a name="line.596"></a>
+<span class="sourceLineNo">597</span>   */<a name="line.597"></a>
+<span class="sourceLineNo">598</span>  public Set&lt;Integer&gt; getLeastFilledBuckets(Set&lt;Integer&gt; excludedBuckets,<a name="line.598"></a>
+<span class="sourceLineNo">599</span>                                            int bucketCount) {<a name="line.599"></a>
+<span class="sourceLineNo">600</span>    Queue&lt;Integer&gt; queue = MinMaxPriorityQueue.&lt;Integer&gt;orderedBy(<a name="line.600"></a>
+<span class="sourceLineNo">601</span>        new Comparator&lt;Integer&gt;() {<a name="line.601"></a>
+<span class="sourceLineNo">602</span>          @Override<a name="line.602"></a>
+<span class="sourceLineNo">603</span>          public int compare(Integer left, Integer right) {<a name="line.603"></a>
+<span class="sourceLineNo">604</span>            // We will always get instantiated buckets<a name="line.604"></a>
+<span class="sourceLineNo">605</span>            return Float.compare(<a name="line.605"></a>
+<span class="sourceLineNo">606</span>                ((float) buckets[left].usedCount) / buckets[left].itemCount,<a name="line.606"></a>
+<span class="sourceLineNo">607</span>                ((float) buckets[right].usedCount) / buckets[right].itemCount);<a name="line.607"></a>
+<span class="sourceLineNo">608</span>          }<a name="line.608"></a>
+<span class="sourceLineNo">609</span>        }).maximumSize(bucketCount).create();<a name="line.609"></a>
+<span class="sourceLineNo">610</span><a name="line.610"></a>
+<span class="sourceLineNo">611</span>    for (int i = 0; i &lt; buckets.length; i ++ ) {<a name="line.611"></a>
+<span class="sourceLineNo">612</span>      if (!excludedBuckets.contains(i) &amp;&amp; !buckets[i].isUninstantiated() &amp;&amp;<a name="line.612"></a>
+<span class="sourceLineNo">613</span>          // Avoid the buckets that are the only buckets for a sizeIndex<a name="line.613"></a>
+<span class="sourceLineNo">614</span>          bucketSizeInfos[buckets[i].sizeIndex()].bucketList.size() != 1) {<a name="line.614"></a>
+<span class="sourceLineNo">615</span>        queue.add(i);<a name="line.615"></a>
+<span class="sourceLineNo">616</span>      }<a name="line.616"></a>
+<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
+<span class="sourceLineNo">618</span><a name="line.618"></a>
+<span class="sourceLineNo">619</span>    Set&lt;Integer&gt; result = new HashSet&lt;&gt;(bucketCount);<a name="line.619"></a>
+<span class="sourceLineNo">620</span>    result.addAll(queue);<a name="line.620"></a>
+<span class="sourceLineNo">621</span><a name="line.621"></a>
+<span class="sourceLineNo">622</span>    return result;<a name="line.622"></a>
+<span class="sourceLineNo">623</span>  }<a name="line.623"></a>
+<span class="sourceLineNo">624</span>}<a name="line.624"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html b/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html
index a3cd853..0a4475b 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.IndexStatistics.html
@@ -277,358 +277,359 @@
 <span class="sourceLineNo">269</span><a name="line.269"></a>
 <span class="sourceLineNo">270</span>  // Default block size in hbase is 64K, so we choose more sizes near 64K, you'd better<a name="line.270"></a>
 <span class="sourceLineNo">271</span>  // reset it according to your cluster's block size distribution<a name="line.271"></a>
-<span class="sourceLineNo">272</span>  // TODO Support the view of block size distribution statistics<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  // TODO: Why we add the extra 1024 bytes? Slop?<a name="line.273"></a>
-<span class="sourceLineNo">274</span>  private static final int DEFAULT_BUCKET_SIZES[] = { 4 * 1024 + 1024, 8 * 1024 + 1024,<a name="line.274"></a>
-<span class="sourceLineNo">275</span>      16 * 1024 + 1024, 32 * 1024 + 1024, 40 * 1024 + 1024, 48 * 1024 + 1024,<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      56 * 1024 + 1024, 64 * 1024 + 1024, 96 * 1024 + 1024, 128 * 1024 + 1024,<a name="line.276"></a>
-<span class="sourceLineNo">277</span>      192 * 1024 + 1024, 256 * 1024 + 1024, 384 * 1024 + 1024,<a name="line.277"></a>
-<span class="sourceLineNo">278</span>      512 * 1024 + 1024 };<a name="line.278"></a>
-<span class="sourceLineNo">279</span><a name="line.279"></a>
-<span class="sourceLineNo">280</span>  /**<a name="line.280"></a>
-<span class="sourceLineNo">281</span>   * Round up the given block size to bucket size, and get the corresponding<a name="line.281"></a>
-<span class="sourceLineNo">282</span>   * BucketSizeInfo<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   */<a name="line.283"></a>
-<span class="sourceLineNo">284</span>  public BucketSizeInfo roundUpToBucketSizeInfo(int blockSize) {<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    for (int i = 0; i &lt; bucketSizes.length; ++i)<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      if (blockSize &lt;= bucketSizes[i])<a name="line.286"></a>
-<span class="sourceLineNo">287</span>        return bucketSizeInfos[i];<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    return null;<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>   * So, what is the minimum amount of items we'll tolerate in a single bucket?<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   */<a name="line.293"></a>
-<span class="sourceLineNo">294</span>  static public final int FEWEST_ITEMS_IN_BUCKET = 4;<a name="line.294"></a>
-<span class="sourceLineNo">295</span><a name="line.295"></a>
-<span class="sourceLineNo">296</span>  private final int[] bucketSizes;<a name="line.296"></a>
-<span class="sourceLineNo">297</span>  private final int bigItemSize;<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  // The capacity size for each bucket<a name="line.298"></a>
-<span class="sourceLineNo">299</span>  private final long bucketCapacity;<a name="line.299"></a>
-<span class="sourceLineNo">300</span>  private Bucket[] buckets;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>  private BucketSizeInfo[] bucketSizeInfos;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>  private final long totalSize;<a name="line.302"></a>
-<span class="sourceLineNo">303</span>  private transient long usedSize = 0;<a name="line.303"></a>
-<span class="sourceLineNo">304</span><a name="line.304"></a>
-<span class="sourceLineNo">305</span>  BucketAllocator(long availableSpace, int[] bucketSizes)<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      throws BucketAllocatorException {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>    this.bucketSizes = bucketSizes == null ? DEFAULT_BUCKET_SIZES : bucketSizes;<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    Arrays.sort(this.bucketSizes);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>    this.bigItemSize = Ints.max(this.bucketSizes);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>    this.bucketCapacity = FEWEST_ITEMS_IN_BUCKET * (long) bigItemSize;<a name="line.310"></a>
-<span class="sourceLineNo">311</span>    buckets = new Bucket[(int) (availableSpace / bucketCapacity)];<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    if (buckets.length &lt; this.bucketSizes.length)<a name="line.312"></a>
-<span class="sourceLineNo">313</span>      throw new BucketAllocatorException("Bucket allocator size too small (" + buckets.length +<a name="line.313"></a>
-<span class="sourceLineNo">314</span>        "); must have room for at least " + this.bucketSizes.length + " buckets");<a name="line.314"></a>
-<span class="sourceLineNo">315</span>    bucketSizeInfos = new BucketSizeInfo[this.bucketSizes.length];<a name="line.315"></a>
-<span class="sourceLineNo">316</span>    for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      bucketSizeInfos[i] = new BucketSizeInfo(i);<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    }<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.319"></a>
-<span class="sourceLineNo">320</span>      buckets[i] = new Bucket(bucketCapacity * i);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>      bucketSizeInfos[i &lt; this.bucketSizes.length ? i : this.bucketSizes.length - 1]<a name="line.321"></a>
-<span class="sourceLineNo">322</span>          .instantiateBucket(buckets[i]);<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    }<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    this.totalSize = ((long) buckets.length) * bucketCapacity;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    if (LOG.isInfoEnabled()) {<a name="line.325"></a>
-<span class="sourceLineNo">326</span>      LOG.info("Cache totalSize=" + this.totalSize + ", buckets=" + this.buckets.length +<a name="line.326"></a>
-<span class="sourceLineNo">327</span>        ", bucket capacity=" + this.bucketCapacity +<a name="line.327"></a>
-<span class="sourceLineNo">328</span>        "=(" + FEWEST_ITEMS_IN_BUCKET + "*" + this.bigItemSize + ")=" +<a name="line.328"></a>
-<span class="sourceLineNo">329</span>        "(FEWEST_ITEMS_IN_BUCKET*(largest configured bucketcache size))");<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 name="line.333"></a>
-<span class="sourceLineNo">334</span>   * Rebuild the allocator's data structures from a persisted map.<a name="line.334"></a>
-<span class="sourceLineNo">335</span>   * @param availableSpace capacity of cache<a name="line.335"></a>
-<span class="sourceLineNo">336</span>   * @param map A map stores the block key and BucketEntry(block's meta data<a name="line.336"></a>
-<span class="sourceLineNo">337</span>   *          like offset, length)<a name="line.337"></a>
-<span class="sourceLineNo">338</span>   * @param realCacheSize cached data size statistics for bucket cache<a name="line.338"></a>
-<span class="sourceLineNo">339</span>   * @throws BucketAllocatorException<a name="line.339"></a>
-<span class="sourceLineNo">340</span>   */<a name="line.340"></a>
-<span class="sourceLineNo">341</span>  BucketAllocator(long availableSpace, int[] bucketSizes, Map&lt;BlockCacheKey, BucketEntry&gt; map,<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      LongAdder realCacheSize) throws BucketAllocatorException {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>    this(availableSpace, bucketSizes);<a name="line.343"></a>
-<span class="sourceLineNo">344</span><a name="line.344"></a>
-<span class="sourceLineNo">345</span>    // each bucket has an offset, sizeindex. probably the buckets are too big<a name="line.345"></a>
-<span class="sourceLineNo">346</span>    // in our default state. so what we do is reconfigure them according to what<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    // we've found. we can only reconfigure each bucket once; if more than once,<a name="line.347"></a>
-<span class="sourceLineNo">348</span>    // we know there's a bug, so we just log the info, throw, and start again...<a name="line.348"></a>
-<span class="sourceLineNo">349</span>    boolean[] reconfigured = new boolean[buckets.length];<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    int sizeNotMatchedCount = 0;<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    int insufficientCapacityCount = 0;<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    Iterator&lt;Map.Entry&lt;BlockCacheKey, BucketEntry&gt;&gt; iterator = map.entrySet().iterator();<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    while (iterator.hasNext()) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>      Map.Entry&lt;BlockCacheKey, BucketEntry&gt; entry = iterator.next();<a name="line.354"></a>
-<span class="sourceLineNo">355</span>      long foundOffset = entry.getValue().offset();<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      int foundLen = entry.getValue().getLength();<a name="line.356"></a>
-<span class="sourceLineNo">357</span>      int bucketSizeIndex = -1;<a name="line.357"></a>
-<span class="sourceLineNo">358</span>      for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>        if (foundLen &lt;= this.bucketSizes[i]) {<a name="line.359"></a>
-<span class="sourceLineNo">360</span>          bucketSizeIndex = i;<a name="line.360"></a>
-<span class="sourceLineNo">361</span>          break;<a name="line.361"></a>
-<span class="sourceLineNo">362</span>        }<a name="line.362"></a>
-<span class="sourceLineNo">363</span>      }<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      if (bucketSizeIndex == -1) {<a name="line.364"></a>
-<span class="sourceLineNo">365</span>        sizeNotMatchedCount++;<a name="line.365"></a>
-<span class="sourceLineNo">366</span>        iterator.remove();<a name="line.366"></a>
-<span class="sourceLineNo">367</span>        continue;<a name="line.367"></a>
-<span class="sourceLineNo">368</span>      }<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      int bucketNo = (int) (foundOffset / bucketCapacity);<a name="line.369"></a>
-<span class="sourceLineNo">370</span>      if (bucketNo &lt; 0 || bucketNo &gt;= buckets.length) {<a name="line.370"></a>
-<span class="sourceLineNo">371</span>        insufficientCapacityCount++;<a name="line.371"></a>
-<span class="sourceLineNo">372</span>        iterator.remove();<a name="line.372"></a>
-<span class="sourceLineNo">373</span>        continue;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>      }<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      Bucket b = buckets[bucketNo];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>      if (reconfigured[bucketNo]) {<a name="line.376"></a>
-<span class="sourceLineNo">377</span>        if (b.sizeIndex() != bucketSizeIndex) {<a name="line.377"></a>
-<span class="sourceLineNo">378</span>          throw new BucketAllocatorException("Inconsistent allocation in bucket map;");<a name="line.378"></a>
-<span class="sourceLineNo">379</span>        }<a name="line.379"></a>
-<span class="sourceLineNo">380</span>      } else {<a name="line.380"></a>
-<span class="sourceLineNo">381</span>        if (!b.isCompletelyFree()) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>          throw new BucketAllocatorException(<a name="line.382"></a>
-<span class="sourceLineNo">383</span>              "Reconfiguring bucket " + bucketNo + " but it's already allocated; corrupt data");<a name="line.383"></a>
-<span class="sourceLineNo">384</span>        }<a name="line.384"></a>
-<span class="sourceLineNo">385</span>        // Need to remove the bucket from whichever list it's currently in at<a name="line.385"></a>
-<span class="sourceLineNo">386</span>        // the moment...<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        BucketSizeInfo bsi = bucketSizeInfos[bucketSizeIndex];<a name="line.387"></a>
-<span class="sourceLineNo">388</span>        BucketSizeInfo oldbsi = bucketSizeInfos[b.sizeIndex()];<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        oldbsi.removeBucket(b);<a name="line.389"></a>
-<span class="sourceLineNo">390</span>        bsi.instantiateBucket(b);<a name="line.390"></a>
-<span class="sourceLineNo">391</span>        reconfigured[bucketNo] = true;<a name="line.391"></a>
-<span class="sourceLineNo">392</span>      }<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      realCacheSize.add(foundLen);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      buckets[bucketNo].addAllocation(foundOffset);<a name="line.394"></a>
-<span class="sourceLineNo">395</span>      usedSize += buckets[bucketNo].getItemAllocationSize();<a name="line.395"></a>
-<span class="sourceLineNo">396</span>      bucketSizeInfos[bucketSizeIndex].blockAllocated(b);<a name="line.396"></a>
-<span class="sourceLineNo">397</span>    }<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    if (sizeNotMatchedCount &gt; 0) {<a name="line.399"></a>
-<span class="sourceLineNo">400</span>      LOG.warn("There are " + sizeNotMatchedCount + " blocks which can't be rebuilt because " +<a name="line.400"></a>
-<span class="sourceLineNo">401</span>        "there is no matching bucket size for these blocks");<a name="line.401"></a>
-<span class="sourceLineNo">402</span>    }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>    if (insufficientCapacityCount &gt; 0) {<a name="line.403"></a>
-<span class="sourceLineNo">404</span>      LOG.warn("There are " + insufficientCapacityCount + " blocks which can't be rebuilt - "<a name="line.404"></a>
-<span class="sourceLineNo">405</span>        + "did you shrink the cache?");<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    }<a name="line.406"></a>
-<span class="sourceLineNo">407</span>  }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>  @Override<a name="line.409"></a>
-<span class="sourceLineNo">410</span>  public String toString() {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    StringBuilder sb = new StringBuilder(1024);<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      Bucket b = buckets[i];<a name="line.413"></a>
-<span class="sourceLineNo">414</span>      if (i &gt; 0) sb.append(", ");<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      sb.append("bucket.").append(i).append(": size=").append(b.getItemAllocationSize());<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      sb.append(", freeCount=").append(b.freeCount()).append(", used=").append(b.usedCount());<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    }<a name="line.417"></a>
-<span class="sourceLineNo">418</span>    return sb.toString();<a name="line.418"></a>
-<span class="sourceLineNo">419</span>  }<a name="line.419"></a>
-<span class="sourceLineNo">420</span><a name="line.420"></a>
-<span class="sourceLineNo">421</span>  public long getUsedSize() {<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    return this.usedSize;<a name="line.422"></a>
-<span class="sourceLineNo">423</span>  }<a name="line.423"></a>
-<span class="sourceLineNo">424</span><a name="line.424"></a>
-<span class="sourceLineNo">425</span>  public long getFreeSize() {<a name="line.425"></a>
-<span class="sourceLineNo">426</span>    return this.totalSize - getUsedSize();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>  }<a name="line.427"></a>
-<span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>  public long getTotalSize() {<a name="line.429"></a>
-<span class="sourceLineNo">430</span>    return this.totalSize;<a name="line.430"></a>
-<span class="sourceLineNo">431</span>  }<a name="line.431"></a>
-<span class="sourceLineNo">432</span><a name="line.432"></a>
-<span class="sourceLineNo">433</span>  /**<a name="line.433"></a>
-<span class="sourceLineNo">434</span>   * Allocate a block with specified size. Return the offset<a name="line.434"></a>
-<span class="sourceLineNo">435</span>   * @param blockSize size of block<a name="line.435"></a>
-<span class="sourceLineNo">436</span>   * @throws BucketAllocatorException<a name="line.436"></a>
-<span class="sourceLineNo">437</span>   * @throws CacheFullException<a name="line.437"></a>
-<span class="sourceLineNo">438</span>   * @return the offset in the IOEngine<a name="line.438"></a>
-<span class="sourceLineNo">439</span>   */<a name="line.439"></a>
-<span class="sourceLineNo">440</span>  public synchronized long allocateBlock(int blockSize) throws CacheFullException,<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      BucketAllocatorException {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    assert blockSize &gt; 0;<a name="line.442"></a>
-<span class="sourceLineNo">443</span>    BucketSizeInfo bsi = roundUpToBucketSizeInfo(blockSize);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    if (bsi == null) {<a name="line.444"></a>
-<span class="sourceLineNo">445</span>      throw new BucketAllocatorException("Allocation too big size=" + blockSize +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "; adjust BucketCache sizes " + BlockCacheFactory.BUCKET_CACHE_BUCKETS_KEY +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to accomodate if size seems reasonable and you want it cached.");<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    }<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    long offset = bsi.allocateBlock();<a name="line.449"></a>
-<span class="sourceLineNo">450</span><a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // Ask caller to free up space and try again!<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    if (offset &lt; 0)<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      throw new CacheFullException(blockSize, bsi.sizeIndex());<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    usedSize += bucketSizes[bsi.sizeIndex()];<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    return offset;<a name="line.455"></a>
-<span class="sourceLineNo">456</span>  }<a name="line.456"></a>
-<span class="sourceLineNo">457</span><a name="line.457"></a>
-<span class="sourceLineNo">458</span>  private Bucket grabGlobalCompletelyFreeBucket() {<a name="line.458"></a>
-<span class="sourceLineNo">459</span>    for (BucketSizeInfo bsi : bucketSizeInfos) {<a name="line.459"></a>
-<span class="sourceLineNo">460</span>      Bucket b = bsi.findAndRemoveCompletelyFreeBucket();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>      if (b != null) return b;<a name="line.461"></a>
-<span class="sourceLineNo">462</span>    }<a name="line.462"></a>
-<span class="sourceLineNo">463</span>    return null;<a name="line.463"></a>
-<span class="sourceLineNo">464</span>  }<a name="line.464"></a>
-<span class="sourceLineNo">465</span><a name="line.465"></a>
-<span class="sourceLineNo">466</span>  /**<a name="line.466"></a>
-<span class="sourceLineNo">467</span>   * Free a block with the offset<a name="line.467"></a>
-<span class="sourceLineNo">468</span>   * @param offset block's offset<a name="line.468"></a>
-<span class="sourceLineNo">469</span>   * @return size freed<a name="line.469"></a>
-<span class="sourceLineNo">470</span>   */<a name="line.470"></a>
-<span class="sourceLineNo">471</span>  public synchronized int freeBlock(long offset) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.473"></a>
-<span class="sourceLineNo">474</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.474"></a>
-<span class="sourceLineNo">475</span>    bucketSizeInfos[targetBucket.sizeIndex()].freeBlock(targetBucket, offset);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>    usedSize -= targetBucket.getItemAllocationSize();<a name="line.476"></a>
-<span class="sourceLineNo">477</span>    return targetBucket.getItemAllocationSize();<a name="line.477"></a>
-<span class="sourceLineNo">478</span>  }<a name="line.478"></a>
-<span class="sourceLineNo">479</span><a name="line.479"></a>
-<span class="sourceLineNo">480</span>  public int sizeIndexOfAllocation(long offset) {<a name="line.480"></a>
-<span class="sourceLineNo">481</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.481"></a>
-<span class="sourceLineNo">482</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    return targetBucket.sizeIndex();<a name="line.484"></a>
-<span class="sourceLineNo">485</span>  }<a name="line.485"></a>
-<span class="sourceLineNo">486</span><a name="line.486"></a>
-<span class="sourceLineNo">487</span>  public int sizeOfAllocation(long offset) {<a name="line.487"></a>
-<span class="sourceLineNo">488</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.488"></a>
-<span class="sourceLineNo">489</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.489"></a>
-<span class="sourceLineNo">490</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    return targetBucket.getItemAllocationSize();<a name="line.491"></a>
-<span class="sourceLineNo">492</span>  }<a name="line.492"></a>
-<span class="sourceLineNo">493</span><a name="line.493"></a>
-<span class="sourceLineNo">494</span>  static class IndexStatistics {<a name="line.494"></a>
-<span class="sourceLineNo">495</span>    private long freeCount, usedCount, itemSize, totalCount;<a name="line.495"></a>
-<span class="sourceLineNo">496</span><a name="line.496"></a>
-<span class="sourceLineNo">497</span>    public long freeCount() {<a name="line.497"></a>
-<span class="sourceLineNo">498</span>      return freeCount;<a name="line.498"></a>
-<span class="sourceLineNo">499</span>    }<a name="line.499"></a>
-<span class="sourceLineNo">500</span><a name="line.500"></a>
-<span class="sourceLineNo">501</span>    public long usedCount() {<a name="line.501"></a>
-<span class="sourceLineNo">502</span>      return usedCount;<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    }<a name="line.503"></a>
-<span class="sourceLineNo">504</span><a name="line.504"></a>
-<span class="sourceLineNo">505</span>    public long totalCount() {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      return totalCount;<a name="line.506"></a>
-<span class="sourceLineNo">507</span>    }<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>    public long freeBytes() {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>      return freeCount * itemSize;<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    }<a name="line.511"></a>
-<span class="sourceLineNo">512</span><a name="line.512"></a>
-<span class="sourceLineNo">513</span>    public long usedBytes() {<a name="line.513"></a>
-<span class="sourceLineNo">514</span>      return usedCount * itemSize;<a name="line.514"></a>
-<span class="sourceLineNo">515</span>    }<a name="line.515"></a>
-<span class="sourceLineNo">516</span><a name="line.516"></a>
-<span class="sourceLineNo">517</span>    public long totalBytes() {<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      return totalCount * itemSize;<a name="line.518"></a>
-<span class="sourceLineNo">519</span>    }<a name="line.519"></a>
-<span class="sourceLineNo">520</span><a name="line.520"></a>
-<span class="sourceLineNo">521</span>    public long itemSize() {<a name="line.521"></a>
-<span class="sourceLineNo">522</span>      return itemSize;<a name="line.522"></a>
-<span class="sourceLineNo">523</span>    }<a name="line.523"></a>
-<span class="sourceLineNo">524</span><a name="line.524"></a>
-<span class="sourceLineNo">525</span>    public IndexStatistics(long free, long used, long itemSize) {<a name="line.525"></a>
-<span class="sourceLineNo">526</span>      setTo(free, used, itemSize);<a name="line.526"></a>
-<span class="sourceLineNo">527</span>    }<a name="line.527"></a>
-<span class="sourceLineNo">528</span><a name="line.528"></a>
-<span class="sourceLineNo">529</span>    public IndexStatistics() {<a name="line.529"></a>
-<span class="sourceLineNo">530</span>      setTo(-1, -1, 0);<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    }<a name="line.531"></a>
-<span class="sourceLineNo">532</span><a name="line.532"></a>
-<span class="sourceLineNo">533</span>    public void setTo(long free, long used, long itemSize) {<a name="line.533"></a>
-<span class="sourceLineNo">534</span>      this.itemSize = itemSize;<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      this.freeCount = free;<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      this.usedCount = used;<a name="line.536"></a>
-<span class="sourceLineNo">537</span>      this.totalCount = free + used;<a name="line.537"></a>
-<span class="sourceLineNo">538</span>    }<a name="line.538"></a>
-<span class="sourceLineNo">539</span>  }<a name="line.539"></a>
-<span class="sourceLineNo">540</span><a name="line.540"></a>
-<span class="sourceLineNo">541</span>  public Bucket [] getBuckets() {<a name="line.541"></a>
-<span class="sourceLineNo">542</span>    return this.buckets;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>  }<a name="line.543"></a>
-<span class="sourceLineNo">544</span><a name="line.544"></a>
-<span class="sourceLineNo">545</span>  void logStatistics() {<a name="line.545"></a>
-<span class="sourceLineNo">546</span>    IndexStatistics total = new IndexStatistics();<a name="line.546"></a>
-<span class="sourceLineNo">547</span>    IndexStatistics[] stats = getIndexStatistics(total);<a name="line.547"></a>
-<span class="sourceLineNo">548</span>    LOG.info("Bucket allocator statistics follow:\n");<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    LOG.info("  Free bytes=" + total.freeBytes() + "+; used bytes="<a name="line.549"></a>
-<span class="sourceLineNo">550</span>        + total.usedBytes() + "; total bytes=" + total.totalBytes());<a name="line.550"></a>
-<span class="sourceLineNo">551</span>    for (IndexStatistics s : stats) {<a name="line.551"></a>
-<span class="sourceLineNo">552</span>      LOG.info("  Object size " + s.itemSize() + " used=" + s.usedCount()<a name="line.552"></a>
-<span class="sourceLineNo">553</span>          + "; free=" + s.freeCount() + "; total=" + s.totalCount());<a name="line.553"></a>
-<span class="sourceLineNo">554</span>    }<a name="line.554"></a>
-<span class="sourceLineNo">555</span>  }<a name="line.555"></a>
-<span class="sourceLineNo">556</span><a name="line.556"></a>
-<span class="sourceLineNo">557</span>  IndexStatistics[] getIndexStatistics(IndexStatistics grandTotal) {<a name="line.557"></a>
-<span class="sourceLineNo">558</span>    IndexStatistics[] stats = getIndexStatistics();<a name="line.558"></a>
-<span class="sourceLineNo">559</span>    long totalfree = 0, totalused = 0;<a name="line.559"></a>
-<span class="sourceLineNo">560</span>    for (IndexStatistics stat : stats) {<a name="line.560"></a>
-<span class="sourceLineNo">561</span>      totalfree += stat.freeBytes();<a name="line.561"></a>
-<span class="sourceLineNo">562</span>      totalused += stat.usedBytes();<a name="line.562"></a>
-<span class="sourceLineNo">563</span>    }<a name="line.563"></a>
-<span class="sourceLineNo">564</span>    grandTotal.setTo(totalfree, totalused, 1);<a name="line.564"></a>
-<span class="sourceLineNo">565</span>    return stats;<a name="line.565"></a>
-<span class="sourceLineNo">566</span>  }<a name="line.566"></a>
-<span class="sourceLineNo">567</span><a name="line.567"></a>
-<span class="sourceLineNo">568</span>  IndexStatistics[] getIndexStatistics() {<a name="line.568"></a>
-<span class="sourceLineNo">569</span>    IndexStatistics[] stats = new IndexStatistics[bucketSizes.length];<a name="line.569"></a>
-<span class="sourceLineNo">570</span>    for (int i = 0; i &lt; stats.length; ++i)<a name="line.570"></a>
-<span class="sourceLineNo">571</span>      stats[i] = bucketSizeInfos[i].statistics();<a name="line.571"></a>
-<span class="sourceLineNo">572</span>    return stats;<a name="line.572"></a>
-<span class="sourceLineNo">573</span>  }<a name="line.573"></a>
-<span class="sourceLineNo">574</span><a name="line.574"></a>
-<span class="sourceLineNo">575</span>  public long freeBlock(long freeList[]) {<a name="line.575"></a>
-<span class="sourceLineNo">576</span>    long sz = 0;<a name="line.576"></a>
-<span class="sourceLineNo">577</span>    for (int i = 0; i &lt; freeList.length; ++i)<a name="line.577"></a>
-<span class="sourceLineNo">578</span>      sz += freeBlock(freeList[i]);<a name="line.578"></a>
-<span class="sourceLineNo">579</span>    return sz;<a name="line.579"></a>
-<span class="sourceLineNo">580</span>  }<a name="line.580"></a>
-<span class="sourceLineNo">581</span><a name="line.581"></a>
-<span class="sourceLineNo">582</span>  public int getBucketIndex(long offset) {<a name="line.582"></a>
-<span class="sourceLineNo">583</span>    return (int) (offset / bucketCapacity);<a name="line.583"></a>
-<span class="sourceLineNo">584</span>  }<a name="line.584"></a>
-<span class="sourceLineNo">585</span><a name="line.585"></a>
-<span class="sourceLineNo">586</span>  /**<a name="line.586"></a>
-<span class="sourceLineNo">587</span>   * Returns a set of indices of the buckets that are least filled<a name="line.587"></a>
-<span class="sourceLineNo">588</span>   * excluding the offsets, we also the fully free buckets for the<a name="line.588"></a>
-<span class="sourceLineNo">589</span>   * BucketSizes where everything is empty and they only have one<a name="line.589"></a>
-<span class="sourceLineNo">590</span>   * completely free bucket as a reserved<a name="line.590"></a>
-<span class="sourceLineNo">591</span>   *<a name="line.591"></a>
-<span class="sourceLineNo">592</span>   * @param excludedBuckets the buckets that need to be excluded due to<a name="line.592"></a>
-<span class="sourceLineNo">593</span>   *                        currently being in used<a name="line.593"></a>
-<span class="sourceLineNo">594</span>   * @param bucketCount     max Number of buckets to return<a name="line.594"></a>
-<span class="sourceLineNo">595</span>   * @return set of bucket indices which could be used for eviction<a name="line.595"></a>
-<span class="sourceLineNo">596</span>   */<a name="line.596"></a>
-<span class="sourceLineNo">597</span>  public Set&lt;Integer&gt; getLeastFilledBuckets(Set&lt;Integer&gt; excludedBuckets,<a name="line.597"></a>
-<span class="sourceLineNo">598</span>                                            int bucketCount) {<a name="line.598"></a>
-<span class="sourceLineNo">599</span>    Queue&lt;Integer&gt; queue = MinMaxPriorityQueue.&lt;Integer&gt;orderedBy(<a name="line.599"></a>
-<span class="sourceLineNo">600</span>        new Comparator&lt;Integer&gt;() {<a name="line.600"></a>
-<span class="sourceLineNo">601</span>          @Override<a name="line.601"></a>
-<span class="sourceLineNo">602</span>          public int compare(Integer left, Integer right) {<a name="line.602"></a>
-<span class="sourceLineNo">603</span>            // We will always get instantiated buckets<a name="line.603"></a>
-<span class="sourceLineNo">604</span>            return Float.compare(<a name="line.604"></a>
-<span class="sourceLineNo">605</span>                ((float) buckets[left].usedCount) / buckets[left].itemCount,<a name="line.605"></a>
-<span class="sourceLineNo">606</span>                ((float) buckets[right].usedCount) / buckets[right].itemCount);<a name="line.606"></a>
-<span class="sourceLineNo">607</span>          }<a name="line.607"></a>
-<span class="sourceLineNo">608</span>        }).maximumSize(bucketCount).create();<a name="line.608"></a>
-<span class="sourceLineNo">609</span><a name="line.609"></a>
-<span class="sourceLineNo">610</span>    for (int i = 0; i &lt; buckets.length; i ++ ) {<a name="line.610"></a>
-<span class="sourceLineNo">611</span>      if (!excludedBuckets.contains(i) &amp;&amp; !buckets[i].isUninstantiated() &amp;&amp;<a name="line.611"></a>
-<span class="sourceLineNo">612</span>          // Avoid the buckets that are the only buckets for a sizeIndex<a name="line.612"></a>
-<span class="sourceLineNo">613</span>          bucketSizeInfos[buckets[i].sizeIndex()].bucketList.size() != 1) {<a name="line.613"></a>
-<span class="sourceLineNo">614</span>        queue.add(i);<a name="line.614"></a>
-<span class="sourceLineNo">615</span>      }<a name="line.615"></a>
-<span class="sourceLineNo">616</span>    }<a name="line.616"></a>
-<span class="sourceLineNo">617</span><a name="line.617"></a>
-<span class="sourceLineNo">618</span>    Set&lt;Integer&gt; result = new HashSet&lt;&gt;(bucketCount);<a name="line.618"></a>
-<span class="sourceLineNo">619</span>    result.addAll(queue);<a name="line.619"></a>
-<span class="sourceLineNo">620</span><a name="line.620"></a>
-<span class="sourceLineNo">621</span>    return result;<a name="line.621"></a>
-<span class="sourceLineNo">622</span>  }<a name="line.622"></a>
-<span class="sourceLineNo">623</span>}<a name="line.623"></a>
+<span class="sourceLineNo">272</span>  // The real block size in hfile maybe a little larger than the size we configured ,<a name="line.272"></a>
+<span class="sourceLineNo">273</span>  // so we need add extra 1024 bytes for fit.<a name="line.273"></a>
+<span class="sourceLineNo">274</span>  // TODO Support the view of block size distribution statistics<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  private static final int DEFAULT_BUCKET_SIZES[] = { 4 * 1024 + 1024, 8 * 1024 + 1024,<a name="line.275"></a>
+<span class="sourceLineNo">276</span>      16 * 1024 + 1024, 32 * 1024 + 1024, 40 * 1024 + 1024, 48 * 1024 + 1024,<a name="line.276"></a>
+<span class="sourceLineNo">277</span>      56 * 1024 + 1024, 64 * 1024 + 1024, 96 * 1024 + 1024, 128 * 1024 + 1024,<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      192 * 1024 + 1024, 256 * 1024 + 1024, 384 * 1024 + 1024,<a name="line.278"></a>
+<span class="sourceLineNo">279</span>      512 * 1024 + 1024 };<a name="line.279"></a>
+<span class="sourceLineNo">280</span><a name="line.280"></a>
+<span class="sourceLineNo">281</span>  /**<a name="line.281"></a>
+<span class="sourceLineNo">282</span>   * Round up the given block size to bucket size, and get the corresponding<a name="line.282"></a>
+<span class="sourceLineNo">283</span>   * BucketSizeInfo<a name="line.283"></a>
+<span class="sourceLineNo">284</span>   */<a name="line.284"></a>
+<span class="sourceLineNo">285</span>  public BucketSizeInfo roundUpToBucketSizeInfo(int blockSize) {<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    for (int i = 0; i &lt; bucketSizes.length; ++i)<a name="line.286"></a>
+<span class="sourceLineNo">287</span>      if (blockSize &lt;= bucketSizes[i])<a name="line.287"></a>
+<span class="sourceLineNo">288</span>        return bucketSizeInfos[i];<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    return null;<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>  /**<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   * So, what is the minimum amount of items we'll tolerate in a single bucket?<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
+<span class="sourceLineNo">295</span>  static public final int FEWEST_ITEMS_IN_BUCKET = 4;<a name="line.295"></a>
+<span class="sourceLineNo">296</span><a name="line.296"></a>
+<span class="sourceLineNo">297</span>  private final int[] bucketSizes;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>  private final int bigItemSize;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>  // The capacity size for each bucket<a name="line.299"></a>
+<span class="sourceLineNo">300</span>  private final long bucketCapacity;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>  private Bucket[] buckets;<a name="line.301"></a>
+<span class="sourceLineNo">302</span>  private BucketSizeInfo[] bucketSizeInfos;<a name="line.302"></a>
+<span class="sourceLineNo">303</span>  private final long totalSize;<a name="line.303"></a>
+<span class="sourceLineNo">304</span>  private transient long usedSize = 0;<a name="line.304"></a>
+<span class="sourceLineNo">305</span><a name="line.305"></a>
+<span class="sourceLineNo">306</span>  BucketAllocator(long availableSpace, int[] bucketSizes)<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      throws BucketAllocatorException {<a name="line.307"></a>
+<span class="sourceLineNo">308</span>    this.bucketSizes = bucketSizes == null ? DEFAULT_BUCKET_SIZES : bucketSizes;<a name="line.308"></a>
+<span class="sourceLineNo">309</span>    Arrays.sort(this.bucketSizes);<a name="line.309"></a>
+<span class="sourceLineNo">310</span>    this.bigItemSize = Ints.max(this.bucketSizes);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    this.bucketCapacity = FEWEST_ITEMS_IN_BUCKET * (long) bigItemSize;<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    buckets = new Bucket[(int) (availableSpace / bucketCapacity)];<a name="line.312"></a>
+<span class="sourceLineNo">313</span>    if (buckets.length &lt; this.bucketSizes.length)<a name="line.313"></a>
+<span class="sourceLineNo">314</span>      throw new BucketAllocatorException("Bucket allocator size too small (" + buckets.length +<a name="line.314"></a>
+<span class="sourceLineNo">315</span>        "); must have room for at least " + this.bucketSizes.length + " buckets");<a name="line.315"></a>
+<span class="sourceLineNo">316</span>    bucketSizeInfos = new BucketSizeInfo[this.bucketSizes.length];<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>      bucketSizeInfos[i] = new BucketSizeInfo(i);<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    }<a name="line.319"></a>
+<span class="sourceLineNo">320</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.320"></a>
+<span class="sourceLineNo">321</span>      buckets[i] = new Bucket(bucketCapacity * i);<a name="line.321"></a>
+<span class="sourceLineNo">322</span>      bucketSizeInfos[i &lt; this.bucketSizes.length ? i : this.bucketSizes.length - 1]<a name="line.322"></a>
+<span class="sourceLineNo">323</span>          .instantiateBucket(buckets[i]);<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    }<a name="line.324"></a>
+<span class="sourceLineNo">325</span>    this.totalSize = ((long) buckets.length) * bucketCapacity;<a name="line.325"></a>
+<span class="sourceLineNo">326</span>    if (LOG.isInfoEnabled()) {<a name="line.326"></a>
+<span class="sourceLineNo">327</span>      LOG.info("Cache totalSize=" + this.totalSize + ", buckets=" + this.buckets.length +<a name="line.327"></a>
+<span class="sourceLineNo">328</span>        ", bucket capacity=" + this.bucketCapacity +<a name="line.328"></a>
+<span class="sourceLineNo">329</span>        "=(" + FEWEST_ITEMS_IN_BUCKET + "*" + this.bigItemSize + ")=" +<a name="line.329"></a>
+<span class="sourceLineNo">330</span>        "(FEWEST_ITEMS_IN_BUCKET*(largest configured bucketcache size))");<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 name="line.333"></a>
+<span class="sourceLineNo">334</span>  /**<a name="line.334"></a>
+<span class="sourceLineNo">335</span>   * Rebuild the allocator's data structures from a persisted map.<a name="line.335"></a>
+<span class="sourceLineNo">336</span>   * @param availableSpace capacity of cache<a name="line.336"></a>
+<span class="sourceLineNo">337</span>   * @param map A map stores the block key and BucketEntry(block's meta data<a name="line.337"></a>
+<span class="sourceLineNo">338</span>   *          like offset, length)<a name="line.338"></a>
+<span class="sourceLineNo">339</span>   * @param realCacheSize cached data size statistics for bucket cache<a name="line.339"></a>
+<span class="sourceLineNo">340</span>   * @throws BucketAllocatorException<a name="line.340"></a>
+<span class="sourceLineNo">341</span>   */<a name="line.341"></a>
+<span class="sourceLineNo">342</span>  BucketAllocator(long availableSpace, int[] bucketSizes, Map&lt;BlockCacheKey, BucketEntry&gt; map,<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      LongAdder realCacheSize) throws BucketAllocatorException {<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    this(availableSpace, bucketSizes);<a name="line.344"></a>
+<span class="sourceLineNo">345</span><a name="line.345"></a>
+<span class="sourceLineNo">346</span>    // each bucket has an offset, sizeindex. probably the buckets are too big<a name="line.346"></a>
+<span class="sourceLineNo">347</span>    // in our default state. so what we do is reconfigure them according to what<a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // we've found. we can only reconfigure each bucket once; if more than once,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // we know there's a bug, so we just log the info, throw, and start again...<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    boolean[] reconfigured = new boolean[buckets.length];<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    int sizeNotMatchedCount = 0;<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    int insufficientCapacityCount = 0;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    Iterator&lt;Map.Entry&lt;BlockCacheKey, BucketEntry&gt;&gt; iterator = map.entrySet().iterator();<a name="line.353"></a>
+<span class="sourceLineNo">354</span>    while (iterator.hasNext()) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      Map.Entry&lt;BlockCacheKey, BucketEntry&gt; entry = iterator.next();<a name="line.355"></a>
+<span class="sourceLineNo">356</span>      long foundOffset = entry.getValue().offset();<a name="line.356"></a>
+<span class="sourceLineNo">357</span>      int foundLen = entry.getValue().getLength();<a name="line.357"></a>
+<span class="sourceLineNo">358</span>      int bucketSizeIndex = -1;<a name="line.358"></a>
+<span class="sourceLineNo">359</span>      for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.359"></a>
+<span class="sourceLineNo">360</span>        if (foundLen &lt;= this.bucketSizes[i]) {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>          bucketSizeIndex = i;<a name="line.361"></a>
+<span class="sourceLineNo">362</span>          break;<a name="line.362"></a>
+<span class="sourceLineNo">363</span>        }<a name="line.363"></a>
+<span class="sourceLineNo">364</span>      }<a name="line.364"></a>
+<span class="sourceLineNo">365</span>      if (bucketSizeIndex == -1) {<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        sizeNotMatchedCount++;<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        iterator.remove();<a name="line.367"></a>
+<span class="sourceLineNo">368</span>        continue;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>      }<a name="line.369"></a>
+<span class="sourceLineNo">370</span>      int bucketNo = (int) (foundOffset / bucketCapacity);<a name="line.370"></a>
+<span class="sourceLineNo">371</span>      if (bucketNo &lt; 0 || bucketNo &gt;= buckets.length) {<a name="line.371"></a>
+<span class="sourceLineNo">372</span>        insufficientCapacityCount++;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>        iterator.remove();<a name="line.373"></a>
+<span class="sourceLineNo">374</span>        continue;<a name="line.374"></a>
+<span class="sourceLineNo">375</span>      }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>      Bucket b = buckets[bucketNo];<a name="line.376"></a>
+<span class="sourceLineNo">377</span>      if (reconfigured[bucketNo]) {<a name="line.377"></a>
+<span class="sourceLineNo">378</span>        if (b.sizeIndex() != bucketSizeIndex) {<a name="line.378"></a>
+<span class="sourceLineNo">379</span>          throw new BucketAllocatorException("Inconsistent allocation in bucket map;");<a name="line.379"></a>
+<span class="sourceLineNo">380</span>        }<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      } else {<a name="line.381"></a>
+<span class="sourceLineNo">382</span>        if (!b.isCompletelyFree()) {<a name="line.382"></a>
+<span class="sourceLineNo">383</span>          throw new BucketAllocatorException(<a name="line.383"></a>
+<span class="sourceLineNo">384</span>              "Reconfiguring bucket " + bucketNo + " but it's already allocated; corrupt data");<a name="line.384"></a>
+<span class="sourceLineNo">385</span>        }<a name="line.385"></a>
+<span class="sourceLineNo">386</span>        // Need to remove the bucket from whichever list it's currently in at<a name="line.386"></a>
+<span class="sourceLineNo">387</span>        // the moment...<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        BucketSizeInfo bsi = bucketSizeInfos[bucketSizeIndex];<a name="line.388"></a>
+<span class="sourceLineNo">389</span>        BucketSizeInfo oldbsi = bucketSizeInfos[b.sizeIndex()];<a name="line.389"></a>
+<span class="sourceLineNo">390</span>        oldbsi.removeBucket(b);<a name="line.390"></a>
+<span class="sourceLineNo">391</span>        bsi.instantiateBucket(b);<a name="line.391"></a>
+<span class="sourceLineNo">392</span>        reconfigured[bucketNo] = true;<a name="line.392"></a>
+<span class="sourceLineNo">393</span>      }<a name="line.393"></a>
+<span class="sourceLineNo">394</span>      realCacheSize.add(foundLen);<a name="line.394"></a>
+<span class="sourceLineNo">395</span>      buckets[bucketNo].addAllocation(foundOffset);<a name="line.395"></a>
+<span class="sourceLineNo">396</span>      usedSize += buckets[bucketNo].getItemAllocationSize();<a name="line.396"></a>
+<span class="sourceLineNo">397</span>      bucketSizeInfos[bucketSizeIndex].blockAllocated(b);<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    }<a name="line.398"></a>
+<span class="sourceLineNo">399</span><a name="line.399"></a>
+<span class="sourceLineNo">400</span>    if (sizeNotMatchedCount &gt; 0) {<a name="line.400"></a>
+<span class="sourceLineNo">401</span>      LOG.warn("There are " + sizeNotMatchedCount + " blocks which can't be rebuilt because " +<a name="line.401"></a>
+<span class="sourceLineNo">402</span>        "there is no matching bucket size for these blocks");<a name="line.402"></a>
+<span class="sourceLineNo">403</span>    }<a name="line.403"></a>
+<span class="sourceLineNo">404</span>    if (insufficientCapacityCount &gt; 0) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>      LOG.warn("There are " + insufficientCapacityCount + " blocks which can't be rebuilt - "<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        + "did you shrink the cache?");<a name="line.406"></a>
+<span class="sourceLineNo">407</span>    }<a name="line.407"></a>
+<span class="sourceLineNo">408</span>  }<a name="line.408"></a>
+<span class="sourceLineNo">409</span><a name="line.409"></a>
+<span class="sourceLineNo">410</span>  @Override<a name="line.410"></a>
+<span class="sourceLineNo">411</span>  public String toString() {<a name="line.411"></a>
+<span class="sourceLineNo">412</span>    StringBuilder sb = new StringBuilder(1024);<a name="line.412"></a>
+<span class="sourceLineNo">413</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      Bucket b = buckets[i];<a name="line.414"></a>
+<span class="sourceLineNo">415</span>      if (i &gt; 0) sb.append(", ");<a name="line.415"></a>
+<span class="sourceLineNo">416</span>      sb.append("bucket.").append(i).append(": size=").append(b.getItemAllocationSize());<a name="line.416"></a>
+<span class="sourceLineNo">417</span>      sb.append(", freeCount=").append(b.freeCount()).append(", used=").append(b.usedCount());<a name="line.417"></a>
+<span class="sourceLineNo">418</span>    }<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    return sb.toString();<a name="line.419"></a>
+<span class="sourceLineNo">420</span>  }<a name="line.420"></a>
+<span class="sourceLineNo">421</span><a name="line.421"></a>
+<span class="sourceLineNo">422</span>  public long getUsedSize() {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    return this.usedSize;<a name="line.423"></a>
+<span class="sourceLineNo">424</span>  }<a name="line.424"></a>
+<span class="sourceLineNo">425</span><a name="line.425"></a>
+<span class="sourceLineNo">426</span>  public long getFreeSize() {<a name="line.426"></a>
+<span class="sourceLineNo">427</span>    return this.totalSize - getUsedSize();<a name="line.427"></a>
+<span class="sourceLineNo">428</span>  }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>  public long getTotalSize() {<a name="line.430"></a>
+<span class="sourceLineNo">431</span>    return this.totalSize;<a name="line.431"></a>
+<span class="sourceLineNo">432</span>  }<a name="line.432"></a>
+<span class="sourceLineNo">433</span><a name="line.433"></a>
+<span class="sourceLineNo">434</span>  /**<a name="line.434"></a>
+<span class="sourceLineNo">435</span>   * Allocate a block with specified size. Return the offset<a name="line.435"></a>
+<span class="sourceLineNo">436</span>   * @param blockSize size of block<a name="line.436"></a>
+<span class="sourceLineNo">437</span>   * @throws BucketAllocatorException<a name="line.437"></a>
+<span class="sourceLineNo">438</span>   * @throws CacheFullException<a name="line.438"></a>
+<span class="sourceLineNo">439</span>   * @return the offset in the IOEngine<a name="line.439"></a>
+<span class="sourceLineNo">440</span>   */<a name="line.440"></a>
+<span class="sourceLineNo">441</span>  public synchronized long allocateBlock(int blockSize) throws CacheFullException,<a name="line.441"></a>
+<span class="sourceLineNo">442</span>      BucketAllocatorException {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>    assert blockSize &gt; 0;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>    BucketSizeInfo bsi = roundUpToBucketSizeInfo(blockSize);<a name="line.444"></a>
+<span class="sourceLineNo">445</span>    if (bsi == null) {<a name="line.445"></a>
+<span class="sourceLineNo">446</span>      throw new BucketAllocatorException("Allocation too big size=" + blockSize +<a name="line.446"></a>
+<span class="sourceLineNo">447</span>        "; adjust BucketCache sizes " + BlockCacheFactory.BUCKET_CACHE_BUCKETS_KEY +<a name="line.447"></a>
+<span class="sourceLineNo">448</span>        " to accomodate if size seems reasonable and you want it cached.");<a name="line.448"></a>
+<span class="sourceLineNo">449</span>    }<a name="line.449"></a>
+<span class="sourceLineNo">450</span>    long offset = bsi.allocateBlock();<a name="line.450"></a>
+<span class="sourceLineNo">451</span><a name="line.451"></a>
+<span class="sourceLineNo">452</span>    // Ask caller to free up space and try again!<a name="line.452"></a>
+<span class="sourceLineNo">453</span>    if (offset &lt; 0)<a name="line.453"></a>
+<span class="sourceLineNo">454</span>      throw new CacheFullException(blockSize, bsi.sizeIndex());<a name="line.454"></a>
+<span class="sourceLineNo">455</span>    usedSize += bucketSizes[bsi.sizeIndex()];<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    return offset;<a name="line.456"></a>
+<span class="sourceLineNo">457</span>  }<a name="line.457"></a>
+<span class="sourceLineNo">458</span><a name="line.458"></a>
+<span class="sourceLineNo">459</span>  private Bucket grabGlobalCompletelyFreeBucket() {<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    for (BucketSizeInfo bsi : bucketSizeInfos) {<a name="line.460"></a>
+<span class="sourceLineNo">461</span>      Bucket b = bsi.findAndRemoveCompletelyFreeBucket();<a name="line.461"></a>
+<span class="sourceLineNo">462</span>      if (b != null) return b;<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    }<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    return null;<a name="line.464"></a>
+<span class="sourceLineNo">465</span>  }<a name="line.465"></a>
+<span class="sourceLineNo">466</span><a name="line.466"></a>
+<span class="sourceLineNo">467</span>  /**<a name="line.467"></a>
+<span class="sourceLineNo">468</span>   * Free a block with the offset<a name="line.468"></a>
+<span class="sourceLineNo">469</span>   * @param offset block's offset<a name="line.469"></a>
+<span class="sourceLineNo">470</span>   * @return size freed<a name="line.470"></a>
+<span class="sourceLineNo">471</span>   */<a name="line.471"></a>
+<span class="sourceLineNo">472</span>  public synchronized int freeBlock(long offset) {<a name="line.472"></a>
+<span class="sourceLineNo">473</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.473"></a>
+<span class="sourceLineNo">474</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.474"></a>
+<span class="sourceLineNo">475</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.475"></a>
+<span class="sourceLineNo">476</span>    bucketSizeInfos[targetBucket.sizeIndex()].freeBlock(targetBucket, offset);<a name="line.476"></a>
+<span class="sourceLineNo">477</span>    usedSize -= targetBucket.getItemAllocationSize();<a name="line.477"></a>
+<span class="sourceLineNo">478</span>    return targetBucket.getItemAllocationSize();<a name="line.478"></a>
+<span class="sourceLineNo">479</span>  }<a name="line.479"></a>
+<span class="sourceLineNo">480</span><a name="line.480"></a>
+<span class="sourceLineNo">481</span>  public int sizeIndexOfAllocation(long offset) {<a name="line.481"></a>
+<span class="sourceLineNo">482</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.482"></a>
+<span class="sourceLineNo">483</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.483"></a>
+<span class="sourceLineNo">484</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.484"></a>
+<span class="sourceLineNo">485</span>    return targetBucket.sizeIndex();<a name="line.485"></a>
+<span class="sourceLineNo">486</span>  }<a name="line.486"></a>
+<span class="sourceLineNo">487</span><a name="line.487"></a>
+<span class="sourceLineNo">488</span>  public int sizeOfAllocation(long offset) {<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.489"></a>
+<span class="sourceLineNo">490</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.490"></a>
+<span class="sourceLineNo">491</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.491"></a>
+<span class="sourceLineNo">492</span>    return targetBucket.getItemAllocationSize();<a name="line.492"></a>
+<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
+<span class="sourceLineNo">494</span><a name="line.494"></a>
+<span class="sourceLineNo">495</span>  static class IndexStatistics {<a name="line.495"></a>
+<span class="sourceLineNo">496</span>    private long freeCount, usedCount, itemSize, totalCount;<a name="line.496"></a>
+<span class="sourceLineNo">497</span><a name="line.497"></a>
+<span class="sourceLineNo">498</span>    public long freeCount() {<a name="line.498"></a>
+<span class="sourceLineNo">499</span>      return freeCount;<a name="line.499"></a>
+<span class="sourceLineNo">500</span>    }<a name="line.500"></a>
+<span class="sourceLineNo">501</span><a name="line.501"></a>
+<span class="sourceLineNo">502</span>    public long usedCount() {<a name="line.502"></a>
+<span class="sourceLineNo">503</span>      return usedCount;<a name="line.503"></a>
+<span class="sourceLineNo">504</span>    }<a name="line.504"></a>
+<span class="sourceLineNo">505</span><a name="line.505"></a>
+<span class="sourceLineNo">506</span>    public long totalCount() {<a name="line.506"></a>
+<span class="sourceLineNo">507</span>      return totalCount;<a name="line.507"></a>
+<span class="sourceLineNo">508</span>    }<a name="line.508"></a>
+<span class="sourceLineNo">509</span><a name="line.509"></a>
+<span class="sourceLineNo">510</span>    public long freeBytes() {<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      return freeCount * itemSize;<a name="line.511"></a>
+<span class="sourceLineNo">512</span>    }<a name="line.512"></a>
+<span class="sourceLineNo">513</span><a name="line.513"></a>
+<span class="sourceLineNo">514</span>    public long usedBytes() {<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      return usedCount * itemSize;<a name="line.515"></a>
+<span class="sourceLineNo">516</span>    }<a name="line.516"></a>
+<span class="sourceLineNo">517</span><a name="line.517"></a>
+<span class="sourceLineNo">518</span>    public long totalBytes() {<a name="line.518"></a>
+<span class="sourceLineNo">519</span>      return totalCount * itemSize;<a name="line.519"></a>
+<span class="sourceLineNo">520</span>    }<a name="line.520"></a>
+<span class="sourceLineNo">521</span><a name="line.521"></a>
+<span class="sourceLineNo">522</span>    public long itemSize() {<a name="line.522"></a>
+<span class="sourceLineNo">523</span>      return itemSize;<a name="line.523"></a>
+<span class="sourceLineNo">524</span>    }<a name="line.524"></a>
+<span class="sourceLineNo">525</span><a name="line.525"></a>
+<span class="sourceLineNo">526</span>    public IndexStatistics(long free, long used, long itemSize) {<a name="line.526"></a>
+<span class="sourceLineNo">527</span>      setTo(free, used, itemSize);<a name="line.527"></a>
+<span class="sourceLineNo">528</span>    }<a name="line.528"></a>
+<span class="sourceLineNo">529</span><a name="line.529"></a>
+<span class="sourceLineNo">530</span>    public IndexStatistics() {<a name="line.530"></a>
+<span class="sourceLineNo">531</span>      setTo(-1, -1, 0);<a name="line.531"></a>
+<span class="sourceLineNo">532</span>    }<a name="line.532"></a>
+<span class="sourceLineNo">533</span><a name="line.533"></a>
+<span class="sourceLineNo">534</span>    public void setTo(long free, long used, long itemSize) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>      this.itemSize = itemSize;<a name="line.535"></a>
+<span class="sourceLineNo">536</span>      this.freeCount = free;<a name="line.536"></a>
+<span class="sourceLineNo">537</span>      this.usedCount = used;<a name="line.537"></a>
+<span class="sourceLineNo">538</span>      this.totalCount = free + used;<a name="line.538"></a>
+<span class="sourceLineNo">539</span>    }<a name="line.539"></a>
+<span class="sourceLineNo">540</span>  }<a name="line.540"></a>
+<span class="sourceLineNo">541</span><a name="line.541"></a>
+<span class="sourceLineNo">542</span>  public Bucket [] getBuckets() {<a name="line.542"></a>
+<span class="sourceLineNo">543</span>    return this.buckets;<a name="line.543"></a>
+<span class="sourceLineNo">544</span>  }<a name="line.544"></a>
+<span class="sourceLineNo">545</span><a name="line.545"></a>
+<span class="sourceLineNo">546</span>  void logStatistics() {<a name="line.546"></a>
+<span class="sourceLineNo">547</span>    IndexStatistics total = new IndexStatistics();<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    IndexStatistics[] stats = getIndexStatistics(total);<a name="line.548"></a>
+<span class="sourceLineNo">549</span>    LOG.info("Bucket allocator statistics follow:\n");<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    LOG.info("  Free bytes=" + total.freeBytes() + "+; used bytes="<a name="line.550"></a>
+<span class="sourceLineNo">551</span>        + total.usedBytes() + "; total bytes=" + total.totalBytes());<a name="line.551"></a>
+<span class="sourceLineNo">552</span>    for (IndexStatistics s : stats) {<a name="line.552"></a>
+<span class="sourceLineNo">553</span>      LOG.info("  Object size " + s.itemSize() + " used=" + s.usedCount()<a name="line.553"></a>
+<span class="sourceLineNo">554</span>          + "; free=" + s.freeCount() + "; total=" + s.totalCount());<a name="line.554"></a>
+<span class="sourceLineNo">555</span>    }<a name="line.555"></a>
+<span class="sourceLineNo">556</span>  }<a name="line.556"></a>
+<span class="sourceLineNo">557</span><a name="line.557"></a>
+<span class="sourceLineNo">558</span>  IndexStatistics[] getIndexStatistics(IndexStatistics grandTotal) {<a name="line.558"></a>
+<span class="sourceLineNo">559</span>    IndexStatistics[] stats = getIndexStatistics();<a name="line.559"></a>
+<span class="sourceLineNo">560</span>    long totalfree = 0, totalused = 0;<a name="line.560"></a>
+<span class="sourceLineNo">561</span>    for (IndexStatistics stat : stats) {<a name="line.561"></a>
+<span class="sourceLineNo">562</span>      totalfree += stat.freeBytes();<a name="line.562"></a>
+<span class="sourceLineNo">563</span>      totalused += stat.usedBytes();<a name="line.563"></a>
+<span class="sourceLineNo">564</span>    }<a name="line.564"></a>
+<span class="sourceLineNo">565</span>    grandTotal.setTo(totalfree, totalused, 1);<a name="line.565"></a>
+<span class="sourceLineNo">566</span>    return stats;<a name="line.566"></a>
+<span class="sourceLineNo">567</span>  }<a name="line.567"></a>
+<span class="sourceLineNo">568</span><a name="line.568"></a>
+<span class="sourceLineNo">569</span>  IndexStatistics[] getIndexStatistics() {<a name="line.569"></a>
+<span class="sourceLineNo">570</span>    IndexStatistics[] stats = new IndexStatistics[bucketSizes.length];<a name="line.570"></a>
+<span class="sourceLineNo">571</span>    for (int i = 0; i &lt; stats.length; ++i)<a name="line.571"></a>
+<span class="sourceLineNo">572</span>      stats[i] = bucketSizeInfos[i].statistics();<a name="line.572"></a>
+<span class="sourceLineNo">573</span>    return stats;<a name="line.573"></a>
+<span class="sourceLineNo">574</span>  }<a name="line.574"></a>
+<span class="sourceLineNo">575</span><a name="line.575"></a>
+<span class="sourceLineNo">576</span>  public long freeBlock(long freeList[]) {<a name="line.576"></a>
+<span class="sourceLineNo">577</span>    long sz = 0;<a name="line.577"></a>
+<span class="sourceLineNo">578</span>    for (int i = 0; i &lt; freeList.length; ++i)<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      sz += freeBlock(freeList[i]);<a name="line.579"></a>
+<span class="sourceLineNo">580</span>    return sz;<a name="line.580"></a>
+<span class="sourceLineNo">581</span>  }<a name="line.581"></a>
+<span class="sourceLineNo">582</span><a name="line.582"></a>
+<span class="sourceLineNo">583</span>  public int getBucketIndex(long offset) {<a name="line.583"></a>
+<span class="sourceLineNo">584</span>    return (int) (offset / bucketCapacity);<a name="line.584"></a>
+<span class="sourceLineNo">585</span>  }<a name="line.585"></a>
+<span class="sourceLineNo">586</span><a name="line.586"></a>
+<span class="sourceLineNo">587</span>  /**<a name="line.587"></a>
+<span class="sourceLineNo">588</span>   * Returns a set of indices of the buckets that are least filled<a name="line.588"></a>
+<span class="sourceLineNo">589</span>   * excluding the offsets, we also the fully free buckets for the<a name="line.589"></a>
+<span class="sourceLineNo">590</span>   * BucketSizes where everything is empty and they only have one<a name="line.590"></a>
+<span class="sourceLineNo">591</span>   * completely free bucket as a reserved<a name="line.591"></a>
+<span class="sourceLineNo">592</span>   *<a name="line.592"></a>
+<span class="sourceLineNo">593</span>   * @param excludedBuckets the buckets that need to be excluded due to<a name="line.593"></a>
+<span class="sourceLineNo">594</span>   *                        currently being in used<a name="line.594"></a>
+<span class="sourceLineNo">595</span>   * @param bucketCount     max Number of buckets to return<a name="line.595"></a>
+<span class="sourceLineNo">596</span>   * @return set of bucket indices which could be used for eviction<a name="line.596"></a>
+<span class="sourceLineNo">597</span>   */<a name="line.597"></a>
+<span class="sourceLineNo">598</span>  public Set&lt;Integer&gt; getLeastFilledBuckets(Set&lt;Integer&gt; excludedBuckets,<a name="line.598"></a>
+<span class="sourceLineNo">599</span>                                            int bucketCount) {<a name="line.599"></a>
+<span class="sourceLineNo">600</span>    Queue&lt;Integer&gt; queue = MinMaxPriorityQueue.&lt;Integer&gt;orderedBy(<a name="line.600"></a>
+<span class="sourceLineNo">601</span>        new Comparator&lt;Integer&gt;() {<a name="line.601"></a>
+<span class="sourceLineNo">602</span>          @Override<a name="line.602"></a>
+<span class="sourceLineNo">603</span>          public int compare(Integer left, Integer right) {<a name="line.603"></a>
+<span class="sourceLineNo">604</span>            // We will always get instantiated buckets<a name="line.604"></a>
+<span class="sourceLineNo">605</span>            return Float.compare(<a name="line.605"></a>
+<span class="sourceLineNo">606</span>                ((float) buckets[left].usedCount) / buckets[left].itemCount,<a name="line.606"></a>
+<span class="sourceLineNo">607</span>                ((float) buckets[right].usedCount) / buckets[right].itemCount);<a name="line.607"></a>
+<span class="sourceLineNo">608</span>          }<a name="line.608"></a>
+<span class="sourceLineNo">609</span>        }).maximumSize(bucketCount).create();<a name="line.609"></a>
+<span class="sourceLineNo">610</span><a name="line.610"></a>
+<span class="sourceLineNo">611</span>    for (int i = 0; i &lt; buckets.length; i ++ ) {<a name="line.611"></a>
+<span class="sourceLineNo">612</span>      if (!excludedBuckets.contains(i) &amp;&amp; !buckets[i].isUninstantiated() &amp;&amp;<a name="line.612"></a>
+<span class="sourceLineNo">613</span>          // Avoid the buckets that are the only buckets for a sizeIndex<a name="line.613"></a>
+<span class="sourceLineNo">614</span>          bucketSizeInfos[buckets[i].sizeIndex()].bucketList.size() != 1) {<a name="line.614"></a>
+<span class="sourceLineNo">615</span>        queue.add(i);<a name="line.615"></a>
+<span class="sourceLineNo">616</span>      }<a name="line.616"></a>
+<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
+<span class="sourceLineNo">618</span><a name="line.618"></a>
+<span class="sourceLineNo">619</span>    Set&lt;Integer&gt; result = new HashSet&lt;&gt;(bucketCount);<a name="line.619"></a>
+<span class="sourceLineNo">620</span>    result.addAll(queue);<a name="line.620"></a>
+<span class="sourceLineNo">621</span><a name="line.621"></a>
+<span class="sourceLineNo">622</span>    return result;<a name="line.622"></a>
+<span class="sourceLineNo">623</span>  }<a name="line.623"></a>
+<span class="sourceLineNo">624</span>}<a name="line.624"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html b/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html
index a3cd853..0a4475b 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.html
@@ -277,358 +277,359 @@
 <span class="sourceLineNo">269</span><a name="line.269"></a>
 <span class="sourceLineNo">270</span>  // Default block size in hbase is 64K, so we choose more sizes near 64K, you'd better<a name="line.270"></a>
 <span class="sourceLineNo">271</span>  // reset it according to your cluster's block size distribution<a name="line.271"></a>
-<span class="sourceLineNo">272</span>  // TODO Support the view of block size distribution statistics<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  // TODO: Why we add the extra 1024 bytes? Slop?<a name="line.273"></a>
-<span class="sourceLineNo">274</span>  private static final int DEFAULT_BUCKET_SIZES[] = { 4 * 1024 + 1024, 8 * 1024 + 1024,<a name="line.274"></a>
-<span class="sourceLineNo">275</span>      16 * 1024 + 1024, 32 * 1024 + 1024, 40 * 1024 + 1024, 48 * 1024 + 1024,<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      56 * 1024 + 1024, 64 * 1024 + 1024, 96 * 1024 + 1024, 128 * 1024 + 1024,<a name="line.276"></a>
-<span class="sourceLineNo">277</span>      192 * 1024 + 1024, 256 * 1024 + 1024, 384 * 1024 + 1024,<a name="line.277"></a>
-<span class="sourceLineNo">278</span>      512 * 1024 + 1024 };<a name="line.278"></a>
-<span class="sourceLineNo">279</span><a name="line.279"></a>
-<span class="sourceLineNo">280</span>  /**<a name="line.280"></a>
-<span class="sourceLineNo">281</span>   * Round up the given block size to bucket size, and get the corresponding<a name="line.281"></a>
-<span class="sourceLineNo">282</span>   * BucketSizeInfo<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   */<a name="line.283"></a>
-<span class="sourceLineNo">284</span>  public BucketSizeInfo roundUpToBucketSizeInfo(int blockSize) {<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    for (int i = 0; i &lt; bucketSizes.length; ++i)<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      if (blockSize &lt;= bucketSizes[i])<a name="line.286"></a>
-<span class="sourceLineNo">287</span>        return bucketSizeInfos[i];<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    return null;<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>   * So, what is the minimum amount of items we'll tolerate in a single bucket?<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   */<a name="line.293"></a>
-<span class="sourceLineNo">294</span>  static public final int FEWEST_ITEMS_IN_BUCKET = 4;<a name="line.294"></a>
-<span class="sourceLineNo">295</span><a name="line.295"></a>
-<span class="sourceLineNo">296</span>  private final int[] bucketSizes;<a name="line.296"></a>
-<span class="sourceLineNo">297</span>  private final int bigItemSize;<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  // The capacity size for each bucket<a name="line.298"></a>
-<span class="sourceLineNo">299</span>  private final long bucketCapacity;<a name="line.299"></a>
-<span class="sourceLineNo">300</span>  private Bucket[] buckets;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>  private BucketSizeInfo[] bucketSizeInfos;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>  private final long totalSize;<a name="line.302"></a>
-<span class="sourceLineNo">303</span>  private transient long usedSize = 0;<a name="line.303"></a>
-<span class="sourceLineNo">304</span><a name="line.304"></a>
-<span class="sourceLineNo">305</span>  BucketAllocator(long availableSpace, int[] bucketSizes)<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      throws BucketAllocatorException {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>    this.bucketSizes = bucketSizes == null ? DEFAULT_BUCKET_SIZES : bucketSizes;<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    Arrays.sort(this.bucketSizes);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>    this.bigItemSize = Ints.max(this.bucketSizes);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>    this.bucketCapacity = FEWEST_ITEMS_IN_BUCKET * (long) bigItemSize;<a name="line.310"></a>
-<span class="sourceLineNo">311</span>    buckets = new Bucket[(int) (availableSpace / bucketCapacity)];<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    if (buckets.length &lt; this.bucketSizes.length)<a name="line.312"></a>
-<span class="sourceLineNo">313</span>      throw new BucketAllocatorException("Bucket allocator size too small (" + buckets.length +<a name="line.313"></a>
-<span class="sourceLineNo">314</span>        "); must have room for at least " + this.bucketSizes.length + " buckets");<a name="line.314"></a>
-<span class="sourceLineNo">315</span>    bucketSizeInfos = new BucketSizeInfo[this.bucketSizes.length];<a name="line.315"></a>
-<span class="sourceLineNo">316</span>    for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      bucketSizeInfos[i] = new BucketSizeInfo(i);<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    }<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.319"></a>
-<span class="sourceLineNo">320</span>      buckets[i] = new Bucket(bucketCapacity * i);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>      bucketSizeInfos[i &lt; this.bucketSizes.length ? i : this.bucketSizes.length - 1]<a name="line.321"></a>
-<span class="sourceLineNo">322</span>          .instantiateBucket(buckets[i]);<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    }<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    this.totalSize = ((long) buckets.length) * bucketCapacity;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    if (LOG.isInfoEnabled()) {<a name="line.325"></a>
-<span class="sourceLineNo">326</span>      LOG.info("Cache totalSize=" + this.totalSize + ", buckets=" + this.buckets.length +<a name="line.326"></a>
-<span class="sourceLineNo">327</span>        ", bucket capacity=" + this.bucketCapacity +<a name="line.327"></a>
-<span class="sourceLineNo">328</span>        "=(" + FEWEST_ITEMS_IN_BUCKET + "*" + this.bigItemSize + ")=" +<a name="line.328"></a>
-<span class="sourceLineNo">329</span>        "(FEWEST_ITEMS_IN_BUCKET*(largest configured bucketcache size))");<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 name="line.333"></a>
-<span class="sourceLineNo">334</span>   * Rebuild the allocator's data structures from a persisted map.<a name="line.334"></a>
-<span class="sourceLineNo">335</span>   * @param availableSpace capacity of cache<a name="line.335"></a>
-<span class="sourceLineNo">336</span>   * @param map A map stores the block key and BucketEntry(block's meta data<a name="line.336"></a>
-<span class="sourceLineNo">337</span>   *          like offset, length)<a name="line.337"></a>
-<span class="sourceLineNo">338</span>   * @param realCacheSize cached data size statistics for bucket cache<a name="line.338"></a>
-<span class="sourceLineNo">339</span>   * @throws BucketAllocatorException<a name="line.339"></a>
-<span class="sourceLineNo">340</span>   */<a name="line.340"></a>
-<span class="sourceLineNo">341</span>  BucketAllocator(long availableSpace, int[] bucketSizes, Map&lt;BlockCacheKey, BucketEntry&gt; map,<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      LongAdder realCacheSize) throws BucketAllocatorException {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>    this(availableSpace, bucketSizes);<a name="line.343"></a>
-<span class="sourceLineNo">344</span><a name="line.344"></a>
-<span class="sourceLineNo">345</span>    // each bucket has an offset, sizeindex. probably the buckets are too big<a name="line.345"></a>
-<span class="sourceLineNo">346</span>    // in our default state. so what we do is reconfigure them according to what<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    // we've found. we can only reconfigure each bucket once; if more than once,<a name="line.347"></a>
-<span class="sourceLineNo">348</span>    // we know there's a bug, so we just log the info, throw, and start again...<a name="line.348"></a>
-<span class="sourceLineNo">349</span>    boolean[] reconfigured = new boolean[buckets.length];<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    int sizeNotMatchedCount = 0;<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    int insufficientCapacityCount = 0;<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    Iterator&lt;Map.Entry&lt;BlockCacheKey, BucketEntry&gt;&gt; iterator = map.entrySet().iterator();<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    while (iterator.hasNext()) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>      Map.Entry&lt;BlockCacheKey, BucketEntry&gt; entry = iterator.next();<a name="line.354"></a>
-<span class="sourceLineNo">355</span>      long foundOffset = entry.getValue().offset();<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      int foundLen = entry.getValue().getLength();<a name="line.356"></a>
-<span class="sourceLineNo">357</span>      int bucketSizeIndex = -1;<a name="line.357"></a>
-<span class="sourceLineNo">358</span>      for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>        if (foundLen &lt;= this.bucketSizes[i]) {<a name="line.359"></a>
-<span class="sourceLineNo">360</span>          bucketSizeIndex = i;<a name="line.360"></a>
-<span class="sourceLineNo">361</span>          break;<a name="line.361"></a>
-<span class="sourceLineNo">362</span>        }<a name="line.362"></a>
-<span class="sourceLineNo">363</span>      }<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      if (bucketSizeIndex == -1) {<a name="line.364"></a>
-<span class="sourceLineNo">365</span>        sizeNotMatchedCount++;<a name="line.365"></a>
-<span class="sourceLineNo">366</span>        iterator.remove();<a name="line.366"></a>
-<span class="sourceLineNo">367</span>        continue;<a name="line.367"></a>
-<span class="sourceLineNo">368</span>      }<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      int bucketNo = (int) (foundOffset / bucketCapacity);<a name="line.369"></a>
-<span class="sourceLineNo">370</span>      if (bucketNo &lt; 0 || bucketNo &gt;= buckets.length) {<a name="line.370"></a>
-<span class="sourceLineNo">371</span>        insufficientCapacityCount++;<a name="line.371"></a>
-<span class="sourceLineNo">372</span>        iterator.remove();<a name="line.372"></a>
-<span class="sourceLineNo">373</span>        continue;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>      }<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      Bucket b = buckets[bucketNo];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>      if (reconfigured[bucketNo]) {<a name="line.376"></a>
-<span class="sourceLineNo">377</span>        if (b.sizeIndex() != bucketSizeIndex) {<a name="line.377"></a>
-<span class="sourceLineNo">378</span>          throw new BucketAllocatorException("Inconsistent allocation in bucket map;");<a name="line.378"></a>
-<span class="sourceLineNo">379</span>        }<a name="line.379"></a>
-<span class="sourceLineNo">380</span>      } else {<a name="line.380"></a>
-<span class="sourceLineNo">381</span>        if (!b.isCompletelyFree()) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>          throw new BucketAllocatorException(<a name="line.382"></a>
-<span class="sourceLineNo">383</span>              "Reconfiguring bucket " + bucketNo + " but it's already allocated; corrupt data");<a name="line.383"></a>
-<span class="sourceLineNo">384</span>        }<a name="line.384"></a>
-<span class="sourceLineNo">385</span>        // Need to remove the bucket from whichever list it's currently in at<a name="line.385"></a>
-<span class="sourceLineNo">386</span>        // the moment...<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        BucketSizeInfo bsi = bucketSizeInfos[bucketSizeIndex];<a name="line.387"></a>
-<span class="sourceLineNo">388</span>        BucketSizeInfo oldbsi = bucketSizeInfos[b.sizeIndex()];<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        oldbsi.removeBucket(b);<a name="line.389"></a>
-<span class="sourceLineNo">390</span>        bsi.instantiateBucket(b);<a name="line.390"></a>
-<span class="sourceLineNo">391</span>        reconfigured[bucketNo] = true;<a name="line.391"></a>
-<span class="sourceLineNo">392</span>      }<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      realCacheSize.add(foundLen);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      buckets[bucketNo].addAllocation(foundOffset);<a name="line.394"></a>
-<span class="sourceLineNo">395</span>      usedSize += buckets[bucketNo].getItemAllocationSize();<a name="line.395"></a>
-<span class="sourceLineNo">396</span>      bucketSizeInfos[bucketSizeIndex].blockAllocated(b);<a name="line.396"></a>
-<span class="sourceLineNo">397</span>    }<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    if (sizeNotMatchedCount &gt; 0) {<a name="line.399"></a>
-<span class="sourceLineNo">400</span>      LOG.warn("There are " + sizeNotMatchedCount + " blocks which can't be rebuilt because " +<a name="line.400"></a>
-<span class="sourceLineNo">401</span>        "there is no matching bucket size for these blocks");<a name="line.401"></a>
-<span class="sourceLineNo">402</span>    }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>    if (insufficientCapacityCount &gt; 0) {<a name="line.403"></a>
-<span class="sourceLineNo">404</span>      LOG.warn("There are " + insufficientCapacityCount + " blocks which can't be rebuilt - "<a name="line.404"></a>
-<span class="sourceLineNo">405</span>        + "did you shrink the cache?");<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    }<a name="line.406"></a>
-<span class="sourceLineNo">407</span>  }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>  @Override<a name="line.409"></a>
-<span class="sourceLineNo">410</span>  public String toString() {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    StringBuilder sb = new StringBuilder(1024);<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      Bucket b = buckets[i];<a name="line.413"></a>
-<span class="sourceLineNo">414</span>      if (i &gt; 0) sb.append(", ");<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      sb.append("bucket.").append(i).append(": size=").append(b.getItemAllocationSize());<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      sb.append(", freeCount=").append(b.freeCount()).append(", used=").append(b.usedCount());<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    }<a name="line.417"></a>
-<span class="sourceLineNo">418</span>    return sb.toString();<a name="line.418"></a>
-<span class="sourceLineNo">419</span>  }<a name="line.419"></a>
-<span class="sourceLineNo">420</span><a name="line.420"></a>
-<span class="sourceLineNo">421</span>  public long getUsedSize() {<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    return this.usedSize;<a name="line.422"></a>
-<span class="sourceLineNo">423</span>  }<a name="line.423"></a>
-<span class="sourceLineNo">424</span><a name="line.424"></a>
-<span class="sourceLineNo">425</span>  public long getFreeSize() {<a name="line.425"></a>
-<span class="sourceLineNo">426</span>    return this.totalSize - getUsedSize();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>  }<a name="line.427"></a>
-<span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>  public long getTotalSize() {<a name="line.429"></a>
-<span class="sourceLineNo">430</span>    return this.totalSize;<a name="line.430"></a>
-<span class="sourceLineNo">431</span>  }<a name="line.431"></a>
-<span class="sourceLineNo">432</span><a name="line.432"></a>
-<span class="sourceLineNo">433</span>  /**<a name="line.433"></a>
-<span class="sourceLineNo">434</span>   * Allocate a block with specified size. Return the offset<a name="line.434"></a>
-<span class="sourceLineNo">435</span>   * @param blockSize size of block<a name="line.435"></a>
-<span class="sourceLineNo">436</span>   * @throws BucketAllocatorException<a name="line.436"></a>
-<span class="sourceLineNo">437</span>   * @throws CacheFullException<a name="line.437"></a>
-<span class="sourceLineNo">438</span>   * @return the offset in the IOEngine<a name="line.438"></a>
-<span class="sourceLineNo">439</span>   */<a name="line.439"></a>
-<span class="sourceLineNo">440</span>  public synchronized long allocateBlock(int blockSize) throws CacheFullException,<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      BucketAllocatorException {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    assert blockSize &gt; 0;<a name="line.442"></a>
-<span class="sourceLineNo">443</span>    BucketSizeInfo bsi = roundUpToBucketSizeInfo(blockSize);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    if (bsi == null) {<a name="line.444"></a>
-<span class="sourceLineNo">445</span>      throw new BucketAllocatorException("Allocation too big size=" + blockSize +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "; adjust BucketCache sizes " + BlockCacheFactory.BUCKET_CACHE_BUCKETS_KEY +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to accomodate if size seems reasonable and you want it cached.");<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    }<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    long offset = bsi.allocateBlock();<a name="line.449"></a>
-<span class="sourceLineNo">450</span><a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // Ask caller to free up space and try again!<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    if (offset &lt; 0)<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      throw new CacheFullException(blockSize, bsi.sizeIndex());<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    usedSize += bucketSizes[bsi.sizeIndex()];<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    return offset;<a name="line.455"></a>
-<span class="sourceLineNo">456</span>  }<a name="line.456"></a>
-<span class="sourceLineNo">457</span><a name="line.457"></a>
-<span class="sourceLineNo">458</span>  private Bucket grabGlobalCompletelyFreeBucket() {<a name="line.458"></a>
-<span class="sourceLineNo">459</span>    for (BucketSizeInfo bsi : bucketSizeInfos) {<a name="line.459"></a>
-<span class="sourceLineNo">460</span>      Bucket b = bsi.findAndRemoveCompletelyFreeBucket();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>      if (b != null) return b;<a name="line.461"></a>
-<span class="sourceLineNo">462</span>    }<a name="line.462"></a>
-<span class="sourceLineNo">463</span>    return null;<a name="line.463"></a>
-<span class="sourceLineNo">464</span>  }<a name="line.464"></a>
-<span class="sourceLineNo">465</span><a name="line.465"></a>
-<span class="sourceLineNo">466</span>  /**<a name="line.466"></a>
-<span class="sourceLineNo">467</span>   * Free a block with the offset<a name="line.467"></a>
-<span class="sourceLineNo">468</span>   * @param offset block's offset<a name="line.468"></a>
-<span class="sourceLineNo">469</span>   * @return size freed<a name="line.469"></a>
-<span class="sourceLineNo">470</span>   */<a name="line.470"></a>
-<span class="sourceLineNo">471</span>  public synchronized int freeBlock(long offset) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.473"></a>
-<span class="sourceLineNo">474</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.474"></a>
-<span class="sourceLineNo">475</span>    bucketSizeInfos[targetBucket.sizeIndex()].freeBlock(targetBucket, offset);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>    usedSize -= targetBucket.getItemAllocationSize();<a name="line.476"></a>
-<span class="sourceLineNo">477</span>    return targetBucket.getItemAllocationSize();<a name="line.477"></a>
-<span class="sourceLineNo">478</span>  }<a name="line.478"></a>
-<span class="sourceLineNo">479</span><a name="line.479"></a>
-<span class="sourceLineNo">480</span>  public int sizeIndexOfAllocation(long offset) {<a name="line.480"></a>
-<span class="sourceLineNo">481</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.481"></a>
-<span class="sourceLineNo">482</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    return targetBucket.sizeIndex();<a name="line.484"></a>
-<span class="sourceLineNo">485</span>  }<a name="line.485"></a>
-<span class="sourceLineNo">486</span><a name="line.486"></a>
-<span class="sourceLineNo">487</span>  public int sizeOfAllocation(long offset) {<a name="line.487"></a>
-<span class="sourceLineNo">488</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.488"></a>
-<span class="sourceLineNo">489</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.489"></a>
-<span class="sourceLineNo">490</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    return targetBucket.getItemAllocationSize();<a name="line.491"></a>
-<span class="sourceLineNo">492</span>  }<a name="line.492"></a>
-<span class="sourceLineNo">493</span><a name="line.493"></a>
-<span class="sourceLineNo">494</span>  static class IndexStatistics {<a name="line.494"></a>
-<span class="sourceLineNo">495</span>    private long freeCount, usedCount, itemSize, totalCount;<a name="line.495"></a>
-<span class="sourceLineNo">496</span><a name="line.496"></a>
-<span class="sourceLineNo">497</span>    public long freeCount() {<a name="line.497"></a>
-<span class="sourceLineNo">498</span>      return freeCount;<a name="line.498"></a>
-<span class="sourceLineNo">499</span>    }<a name="line.499"></a>
-<span class="sourceLineNo">500</span><a name="line.500"></a>
-<span class="sourceLineNo">501</span>    public long usedCount() {<a name="line.501"></a>
-<span class="sourceLineNo">502</span>      return usedCount;<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    }<a name="line.503"></a>
-<span class="sourceLineNo">504</span><a name="line.504"></a>
-<span class="sourceLineNo">505</span>    public long totalCount() {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      return totalCount;<a name="line.506"></a>
-<span class="sourceLineNo">507</span>    }<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>    public long freeBytes() {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>      return freeCount * itemSize;<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    }<a name="line.511"></a>
-<span class="sourceLineNo">512</span><a name="line.512"></a>
-<span class="sourceLineNo">513</span>    public long usedBytes() {<a name="line.513"></a>
-<span class="sourceLineNo">514</span>      return usedCount * itemSize;<a name="line.514"></a>
-<span class="sourceLineNo">515</span>    }<a name="line.515"></a>
-<span class="sourceLineNo">516</span><a name="line.516"></a>
-<span class="sourceLineNo">517</span>    public long totalBytes() {<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      return totalCount * itemSize;<a name="line.518"></a>
-<span class="sourceLineNo">519</span>    }<a name="line.519"></a>
-<span class="sourceLineNo">520</span><a name="line.520"></a>
-<span class="sourceLineNo">521</span>    public long itemSize() {<a name="line.521"></a>
-<span class="sourceLineNo">522</span>      return itemSize;<a name="line.522"></a>
-<span class="sourceLineNo">523</span>    }<a name="line.523"></a>
-<span class="sourceLineNo">524</span><a name="line.524"></a>
-<span class="sourceLineNo">525</span>    public IndexStatistics(long free, long used, long itemSize) {<a name="line.525"></a>
-<span class="sourceLineNo">526</span>      setTo(free, used, itemSize);<a name="line.526"></a>
-<span class="sourceLineNo">527</span>    }<a name="line.527"></a>
-<span class="sourceLineNo">528</span><a name="line.528"></a>
-<span class="sourceLineNo">529</span>    public IndexStatistics() {<a name="line.529"></a>
-<span class="sourceLineNo">530</span>      setTo(-1, -1, 0);<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    }<a name="line.531"></a>
-<span class="sourceLineNo">532</span><a name="line.532"></a>
-<span class="sourceLineNo">533</span>    public void setTo(long free, long used, long itemSize) {<a name="line.533"></a>
-<span class="sourceLineNo">534</span>      this.itemSize = itemSize;<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      this.freeCount = free;<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      this.usedCount = used;<a name="line.536"></a>
-<span class="sourceLineNo">537</span>      this.totalCount = free + used;<a name="line.537"></a>
-<span class="sourceLineNo">538</span>    }<a name="line.538"></a>
-<span class="sourceLineNo">539</span>  }<a name="line.539"></a>
-<span class="sourceLineNo">540</span><a name="line.540"></a>
-<span class="sourceLineNo">541</span>  public Bucket [] getBuckets() {<a name="line.541"></a>
-<span class="sourceLineNo">542</span>    return this.buckets;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>  }<a name="line.543"></a>
-<span class="sourceLineNo">544</span><a name="line.544"></a>
-<span class="sourceLineNo">545</span>  void logStatistics() {<a name="line.545"></a>
-<span class="sourceLineNo">546</span>    IndexStatistics total = new IndexStatistics();<a name="line.546"></a>
-<span class="sourceLineNo">547</span>    IndexStatistics[] stats = getIndexStatistics(total);<a name="line.547"></a>
-<span class="sourceLineNo">548</span>    LOG.info("Bucket allocator statistics follow:\n");<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    LOG.info("  Free bytes=" + total.freeBytes() + "+; used bytes="<a name="line.549"></a>
-<span class="sourceLineNo">550</span>        + total.usedBytes() + "; total bytes=" + total.totalBytes());<a name="line.550"></a>
-<span class="sourceLineNo">551</span>    for (IndexStatistics s : stats) {<a name="line.551"></a>
-<span class="sourceLineNo">552</span>      LOG.info("  Object size " + s.itemSize() + " used=" + s.usedCount()<a name="line.552"></a>
-<span class="sourceLineNo">553</span>          + "; free=" + s.freeCount() + "; total=" + s.totalCount());<a name="line.553"></a>
-<span class="sourceLineNo">554</span>    }<a name="line.554"></a>
-<span class="sourceLineNo">555</span>  }<a name="line.555"></a>
-<span class="sourceLineNo">556</span><a name="line.556"></a>
-<span class="sourceLineNo">557</span>  IndexStatistics[] getIndexStatistics(IndexStatistics grandTotal) {<a name="line.557"></a>
-<span class="sourceLineNo">558</span>    IndexStatistics[] stats = getIndexStatistics();<a name="line.558"></a>
-<span class="sourceLineNo">559</span>    long totalfree = 0, totalused = 0;<a name="line.559"></a>
-<span class="sourceLineNo">560</span>    for (IndexStatistics stat : stats) {<a name="line.560"></a>
-<span class="sourceLineNo">561</span>      totalfree += stat.freeBytes();<a name="line.561"></a>
-<span class="sourceLineNo">562</span>      totalused += stat.usedBytes();<a name="line.562"></a>
-<span class="sourceLineNo">563</span>    }<a name="line.563"></a>
-<span class="sourceLineNo">564</span>    grandTotal.setTo(totalfree, totalused, 1);<a name="line.564"></a>
-<span class="sourceLineNo">565</span>    return stats;<a name="line.565"></a>
-<span class="sourceLineNo">566</span>  }<a name="line.566"></a>
-<span class="sourceLineNo">567</span><a name="line.567"></a>
-<span class="sourceLineNo">568</span>  IndexStatistics[] getIndexStatistics() {<a name="line.568"></a>
-<span class="sourceLineNo">569</span>    IndexStatistics[] stats = new IndexStatistics[bucketSizes.length];<a name="line.569"></a>
-<span class="sourceLineNo">570</span>    for (int i = 0; i &lt; stats.length; ++i)<a name="line.570"></a>
-<span class="sourceLineNo">571</span>      stats[i] = bucketSizeInfos[i].statistics();<a name="line.571"></a>
-<span class="sourceLineNo">572</span>    return stats;<a name="line.572"></a>
-<span class="sourceLineNo">573</span>  }<a name="line.573"></a>
-<span class="sourceLineNo">574</span><a name="line.574"></a>
-<span class="sourceLineNo">575</span>  public long freeBlock(long freeList[]) {<a name="line.575"></a>
-<span class="sourceLineNo">576</span>    long sz = 0;<a name="line.576"></a>
-<span class="sourceLineNo">577</span>    for (int i = 0; i &lt; freeList.length; ++i)<a name="line.577"></a>
-<span class="sourceLineNo">578</span>      sz += freeBlock(freeList[i]);<a name="line.578"></a>
-<span class="sourceLineNo">579</span>    return sz;<a name="line.579"></a>
-<span class="sourceLineNo">580</span>  }<a name="line.580"></a>
-<span class="sourceLineNo">581</span><a name="line.581"></a>
-<span class="sourceLineNo">582</span>  public int getBucketIndex(long offset) {<a name="line.582"></a>
-<span class="sourceLineNo">583</span>    return (int) (offset / bucketCapacity);<a name="line.583"></a>
-<span class="sourceLineNo">584</span>  }<a name="line.584"></a>
-<span class="sourceLineNo">585</span><a name="line.585"></a>
-<span class="sourceLineNo">586</span>  /**<a name="line.586"></a>
-<span class="sourceLineNo">587</span>   * Returns a set of indices of the buckets that are least filled<a name="line.587"></a>
-<span class="sourceLineNo">588</span>   * excluding the offsets, we also the fully free buckets for the<a name="line.588"></a>
-<span class="sourceLineNo">589</span>   * BucketSizes where everything is empty and they only have one<a name="line.589"></a>
-<span class="sourceLineNo">590</span>   * completely free bucket as a reserved<a name="line.590"></a>
-<span class="sourceLineNo">591</span>   *<a name="line.591"></a>
-<span class="sourceLineNo">592</span>   * @param excludedBuckets the buckets that need to be excluded due to<a name="line.592"></a>
-<span class="sourceLineNo">593</span>   *                        currently being in used<a name="line.593"></a>
-<span class="sourceLineNo">594</span>   * @param bucketCount     max Number of buckets to return<a name="line.594"></a>
-<span class="sourceLineNo">595</span>   * @return set of bucket indices which could be used for eviction<a name="line.595"></a>
-<span class="sourceLineNo">596</span>   */<a name="line.596"></a>
-<span class="sourceLineNo">597</span>  public Set&lt;Integer&gt; getLeastFilledBuckets(Set&lt;Integer&gt; excludedBuckets,<a name="line.597"></a>
-<span class="sourceLineNo">598</span>                                            int bucketCount) {<a name="line.598"></a>
-<span class="sourceLineNo">599</span>    Queue&lt;Integer&gt; queue = MinMaxPriorityQueue.&lt;Integer&gt;orderedBy(<a name="line.599"></a>
-<span class="sourceLineNo">600</span>        new Comparator&lt;Integer&gt;() {<a name="line.600"></a>
-<span class="sourceLineNo">601</span>          @Override<a name="line.601"></a>
-<span class="sourceLineNo">602</span>          public int compare(Integer left, Integer right) {<a name="line.602"></a>
-<span class="sourceLineNo">603</span>            // We will always get instantiated buckets<a name="line.603"></a>
-<span class="sourceLineNo">604</span>            return Float.compare(<a name="line.604"></a>
-<span class="sourceLineNo">605</span>                ((float) buckets[left].usedCount) / buckets[left].itemCount,<a name="line.605"></a>
-<span class="sourceLineNo">606</span>                ((float) buckets[right].usedCount) / buckets[right].itemCount);<a name="line.606"></a>
-<span class="sourceLineNo">607</span>          }<a name="line.607"></a>
-<span class="sourceLineNo">608</span>        }).maximumSize(bucketCount).create();<a name="line.608"></a>
-<span class="sourceLineNo">609</span><a name="line.609"></a>
-<span class="sourceLineNo">610</span>    for (int i = 0; i &lt; buckets.length; i ++ ) {<a name="line.610"></a>
-<span class="sourceLineNo">611</span>      if (!excludedBuckets.contains(i) &amp;&amp; !buckets[i].isUninstantiated() &amp;&amp;<a name="line.611"></a>
-<span class="sourceLineNo">612</span>          // Avoid the buckets that are the only buckets for a sizeIndex<a name="line.612"></a>
-<span class="sourceLineNo">613</span>          bucketSizeInfos[buckets[i].sizeIndex()].bucketList.size() != 1) {<a name="line.613"></a>
-<span class="sourceLineNo">614</span>        queue.add(i);<a name="line.614"></a>
-<span class="sourceLineNo">615</span>      }<a name="line.615"></a>
-<span class="sourceLineNo">616</span>    }<a name="line.616"></a>
-<span class="sourceLineNo">617</span><a name="line.617"></a>
-<span class="sourceLineNo">618</span>    Set&lt;Integer&gt; result = new HashSet&lt;&gt;(bucketCount);<a name="line.618"></a>
-<span class="sourceLineNo">619</span>    result.addAll(queue);<a name="line.619"></a>
-<span class="sourceLineNo">620</span><a name="line.620"></a>
-<span class="sourceLineNo">621</span>    return result;<a name="line.621"></a>
-<span class="sourceLineNo">622</span>  }<a name="line.622"></a>
-<span class="sourceLineNo">623</span>}<a name="line.623"></a>
+<span class="sourceLineNo">272</span>  // The real block size in hfile maybe a little larger than the size we configured ,<a name="line.272"></a>
+<span class="sourceLineNo">273</span>  // so we need add extra 1024 bytes for fit.<a name="line.273"></a>
+<span class="sourceLineNo">274</span>  // TODO Support the view of block size distribution statistics<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  private static final int DEFAULT_BUCKET_SIZES[] = { 4 * 1024 + 1024, 8 * 1024 + 1024,<a name="line.275"></a>
+<span class="sourceLineNo">276</span>      16 * 1024 + 1024, 32 * 1024 + 1024, 40 * 1024 + 1024, 48 * 1024 + 1024,<a name="line.276"></a>
+<span class="sourceLineNo">277</span>      56 * 1024 + 1024, 64 * 1024 + 1024, 96 * 1024 + 1024, 128 * 1024 + 1024,<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      192 * 1024 + 1024, 256 * 1024 + 1024, 384 * 1024 + 1024,<a name="line.278"></a>
+<span class="sourceLineNo">279</span>      512 * 1024 + 1024 };<a name="line.279"></a>
+<span class="sourceLineNo">280</span><a name="line.280"></a>
+<span class="sourceLineNo">281</span>  /**<a name="line.281"></a>
+<span class="sourceLineNo">282</span>   * Round up the given block size to bucket size, and get the corresponding<a name="line.282"></a>
+<span class="sourceLineNo">283</span>   * BucketSizeInfo<a name="line.283"></a>
+<span class="sourceLineNo">284</span>   */<a name="line.284"></a>
+<span class="sourceLineNo">285</span>  public BucketSizeInfo roundUpToBucketSizeInfo(int blockSize) {<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    for (int i = 0; i &lt; bucketSizes.length; ++i)<a name="line.286"></a>
+<span class="sourceLineNo">287</span>      if (blockSize &lt;= bucketSizes[i])<a name="line.287"></a>
+<span class="sourceLineNo">288</span>        return bucketSizeInfos[i];<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    return null;<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>  /**<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   * So, what is the minimum amount of items we'll tolerate in a single bucket?<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
+<span class="sourceLineNo">295</span>  static public final int FEWEST_ITEMS_IN_BUCKET = 4;<a name="line.295"></a>
+<span class="sourceLineNo">296</span><a name="line.296"></a>
+<span class="sourceLineNo">297</span>  private final int[] bucketSizes;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>  private final int bigItemSize;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>  // The capacity size for each bucket<a name="line.299"></a>
+<span class="sourceLineNo">300</span>  private final long bucketCapacity;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>  private Bucket[] buckets;<a name="line.301"></a>
+<span class="sourceLineNo">302</span>  private BucketSizeInfo[] bucketSizeInfos;<a name="line.302"></a>
+<span class="sourceLineNo">303</span>  private final long totalSize;<a name="line.303"></a>
+<span class="sourceLineNo">304</span>  private transient long usedSize = 0;<a name="line.304"></a>
+<span class="sourceLineNo">305</span><a name="line.305"></a>
+<span class="sourceLineNo">306</span>  BucketAllocator(long availableSpace, int[] bucketSizes)<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      throws BucketAllocatorException {<a name="line.307"></a>
+<span class="sourceLineNo">308</span>    this.bucketSizes = bucketSizes == null ? DEFAULT_BUCKET_SIZES : bucketSizes;<a name="line.308"></a>
+<span class="sourceLineNo">309</span>    Arrays.sort(this.bucketSizes);<a name="line.309"></a>
+<span class="sourceLineNo">310</span>    this.bigItemSize = Ints.max(this.bucketSizes);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    this.bucketCapacity = FEWEST_ITEMS_IN_BUCKET * (long) bigItemSize;<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    buckets = new Bucket[(int) (availableSpace / bucketCapacity)];<a name="line.312"></a>
+<span class="sourceLineNo">313</span>    if (buckets.length &lt; this.bucketSizes.length)<a name="line.313"></a>
+<span class="sourceLineNo">314</span>      throw new BucketAllocatorException("Bucket allocator size too small (" + buckets.length +<a name="line.314"></a>
+<span class="sourceLineNo">315</span>        "); must have room for at least " + this.bucketSizes.length + " buckets");<a name="line.315"></a>
+<span class="sourceLineNo">316</span>    bucketSizeInfos = new BucketSizeInfo[this.bucketSizes.length];<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>      bucketSizeInfos[i] = new BucketSizeInfo(i);<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    }<a name="line.319"></a>
+<span class="sourceLineNo">320</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.320"></a>
+<span class="sourceLineNo">321</span>      buckets[i] = new Bucket(bucketCapacity * i);<a name="line.321"></a>
+<span class="sourceLineNo">322</span>      bucketSizeInfos[i &lt; this.bucketSizes.length ? i : this.bucketSizes.length - 1]<a name="line.322"></a>
+<span class="sourceLineNo">323</span>          .instantiateBucket(buckets[i]);<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    }<a name="line.324"></a>
+<span class="sourceLineNo">325</span>    this.totalSize = ((long) buckets.length) * bucketCapacity;<a name="line.325"></a>
+<span class="sourceLineNo">326</span>    if (LOG.isInfoEnabled()) {<a name="line.326"></a>
+<span class="sourceLineNo">327</span>      LOG.info("Cache totalSize=" + this.totalSize + ", buckets=" + this.buckets.length +<a name="line.327"></a>
+<span class="sourceLineNo">328</span>        ", bucket capacity=" + this.bucketCapacity +<a name="line.328"></a>
+<span class="sourceLineNo">329</span>        "=(" + FEWEST_ITEMS_IN_BUCKET + "*" + this.bigItemSize + ")=" +<a name="line.329"></a>
+<span class="sourceLineNo">330</span>        "(FEWEST_ITEMS_IN_BUCKET*(largest configured bucketcache size))");<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 name="line.333"></a>
+<span class="sourceLineNo">334</span>  /**<a name="line.334"></a>
+<span class="sourceLineNo">335</span>   * Rebuild the allocator's data structures from a persisted map.<a name="line.335"></a>
+<span class="sourceLineNo">336</span>   * @param availableSpace capacity of cache<a name="line.336"></a>
+<span class="sourceLineNo">337</span>   * @param map A map stores the block key and BucketEntry(block's meta data<a name="line.337"></a>
+<span class="sourceLineNo">338</span>   *          like offset, length)<a name="line.338"></a>
+<span class="sourceLineNo">339</span>   * @param realCacheSize cached data size statistics for bucket cache<a name="line.339"></a>
+<span class="sourceLineNo">340</span>   * @throws BucketAllocatorException<a name="line.340"></a>
+<span class="sourceLineNo">341</span>   */<a name="line.341"></a>
+<span class="sourceLineNo">342</span>  BucketAllocator(long availableSpace, int[] bucketSizes, Map&lt;BlockCacheKey, BucketEntry&gt; map,<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      LongAdder realCacheSize) throws BucketAllocatorException {<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    this(availableSpace, bucketSizes);<a name="line.344"></a>
+<span class="sourceLineNo">345</span><a name="line.345"></a>
+<span class="sourceLineNo">346</span>    // each bucket has an offset, sizeindex. probably the buckets are too big<a name="line.346"></a>
+<span class="sourceLineNo">347</span>    // in our default state. so what we do is reconfigure them according to what<a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // we've found. we can only reconfigure each bucket once; if more than once,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // we know there's a bug, so we just log the info, throw, and start again...<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    boolean[] reconfigured = new boolean[buckets.length];<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    int sizeNotMatchedCount = 0;<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    int insufficientCapacityCount = 0;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    Iterator&lt;Map.Entry&lt;BlockCacheKey, BucketEntry&gt;&gt; iterator = map.entrySet().iterator();<a name="line.353"></a>
+<span class="sourceLineNo">354</span>    while (iterator.hasNext()) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      Map.Entry&lt;BlockCacheKey, BucketEntry&gt; entry = iterator.next();<a name="line.355"></a>
+<span class="sourceLineNo">356</span>      long foundOffset = entry.getValue().offset();<a name="line.356"></a>
+<span class="sourceLineNo">357</span>      int foundLen = entry.getValue().getLength();<a name="line.357"></a>
+<span class="sourceLineNo">358</span>      int bucketSizeIndex = -1;<a name="line.358"></a>
+<span class="sourceLineNo">359</span>      for (int i = 0; i &lt; this.bucketSizes.length; ++i) {<a name="line.359"></a>
+<span class="sourceLineNo">360</span>        if (foundLen &lt;= this.bucketSizes[i]) {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>          bucketSizeIndex = i;<a name="line.361"></a>
+<span class="sourceLineNo">362</span>          break;<a name="line.362"></a>
+<span class="sourceLineNo">363</span>        }<a name="line.363"></a>
+<span class="sourceLineNo">364</span>      }<a name="line.364"></a>
+<span class="sourceLineNo">365</span>      if (bucketSizeIndex == -1) {<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        sizeNotMatchedCount++;<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        iterator.remove();<a name="line.367"></a>
+<span class="sourceLineNo">368</span>        continue;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>      }<a name="line.369"></a>
+<span class="sourceLineNo">370</span>      int bucketNo = (int) (foundOffset / bucketCapacity);<a name="line.370"></a>
+<span class="sourceLineNo">371</span>      if (bucketNo &lt; 0 || bucketNo &gt;= buckets.length) {<a name="line.371"></a>
+<span class="sourceLineNo">372</span>        insufficientCapacityCount++;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>        iterator.remove();<a name="line.373"></a>
+<span class="sourceLineNo">374</span>        continue;<a name="line.374"></a>
+<span class="sourceLineNo">375</span>      }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>      Bucket b = buckets[bucketNo];<a name="line.376"></a>
+<span class="sourceLineNo">377</span>      if (reconfigured[bucketNo]) {<a name="line.377"></a>
+<span class="sourceLineNo">378</span>        if (b.sizeIndex() != bucketSizeIndex) {<a name="line.378"></a>
+<span class="sourceLineNo">379</span>          throw new BucketAllocatorException("Inconsistent allocation in bucket map;");<a name="line.379"></a>
+<span class="sourceLineNo">380</span>        }<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      } else {<a name="line.381"></a>
+<span class="sourceLineNo">382</span>        if (!b.isCompletelyFree()) {<a name="line.382"></a>
+<span class="sourceLineNo">383</span>          throw new BucketAllocatorException(<a name="line.383"></a>
+<span class="sourceLineNo">384</span>              "Reconfiguring bucket " + bucketNo + " but it's already allocated; corrupt data");<a name="line.384"></a>
+<span class="sourceLineNo">385</span>        }<a name="line.385"></a>
+<span class="sourceLineNo">386</span>        // Need to remove the bucket from whichever list it's currently in at<a name="line.386"></a>
+<span class="sourceLineNo">387</span>        // the moment...<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        BucketSizeInfo bsi = bucketSizeInfos[bucketSizeIndex];<a name="line.388"></a>
+<span class="sourceLineNo">389</span>        BucketSizeInfo oldbsi = bucketSizeInfos[b.sizeIndex()];<a name="line.389"></a>
+<span class="sourceLineNo">390</span>        oldbsi.removeBucket(b);<a name="line.390"></a>
+<span class="sourceLineNo">391</span>        bsi.instantiateBucket(b);<a name="line.391"></a>
+<span class="sourceLineNo">392</span>        reconfigured[bucketNo] = true;<a name="line.392"></a>
+<span class="sourceLineNo">393</span>      }<a name="line.393"></a>
+<span class="sourceLineNo">394</span>      realCacheSize.add(foundLen);<a name="line.394"></a>
+<span class="sourceLineNo">395</span>      buckets[bucketNo].addAllocation(foundOffset);<a name="line.395"></a>
+<span class="sourceLineNo">396</span>      usedSize += buckets[bucketNo].getItemAllocationSize();<a name="line.396"></a>
+<span class="sourceLineNo">397</span>      bucketSizeInfos[bucketSizeIndex].blockAllocated(b);<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    }<a name="line.398"></a>
+<span class="sourceLineNo">399</span><a name="line.399"></a>
+<span class="sourceLineNo">400</span>    if (sizeNotMatchedCount &gt; 0) {<a name="line.400"></a>
+<span class="sourceLineNo">401</span>      LOG.warn("There are " + sizeNotMatchedCount + " blocks which can't be rebuilt because " +<a name="line.401"></a>
+<span class="sourceLineNo">402</span>        "there is no matching bucket size for these blocks");<a name="line.402"></a>
+<span class="sourceLineNo">403</span>    }<a name="line.403"></a>
+<span class="sourceLineNo">404</span>    if (insufficientCapacityCount &gt; 0) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>      LOG.warn("There are " + insufficientCapacityCount + " blocks which can't be rebuilt - "<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        + "did you shrink the cache?");<a name="line.406"></a>
+<span class="sourceLineNo">407</span>    }<a name="line.407"></a>
+<span class="sourceLineNo">408</span>  }<a name="line.408"></a>
+<span class="sourceLineNo">409</span><a name="line.409"></a>
+<span class="sourceLineNo">410</span>  @Override<a name="line.410"></a>
+<span class="sourceLineNo">411</span>  public String toString() {<a name="line.411"></a>
+<span class="sourceLineNo">412</span>    StringBuilder sb = new StringBuilder(1024);<a name="line.412"></a>
+<span class="sourceLineNo">413</span>    for (int i = 0; i &lt; buckets.length; ++i) {<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      Bucket b = buckets[i];<a name="line.414"></a>
+<span class="sourceLineNo">415</span>      if (i &gt; 0) sb.append(", ");<a name="line.415"></a>
+<span class="sourceLineNo">416</span>      sb.append("bucket.").append(i).append(": size=").append(b.getItemAllocationSize());<a name="line.416"></a>
+<span class="sourceLineNo">417</span>      sb.append(", freeCount=").append(b.freeCount()).append(", used=").append(b.usedCount());<a name="line.417"></a>
+<span class="sourceLineNo">418</span>    }<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    return sb.toString();<a name="line.419"></a>
+<span class="sourceLineNo">420</span>  }<a name="line.420"></a>
+<span class="sourceLineNo">421</span><a name="line.421"></a>
+<span class="sourceLineNo">422</span>  public long getUsedSize() {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    return this.usedSize;<a name="line.423"></a>
+<span class="sourceLineNo">424</span>  }<a name="line.424"></a>
+<span class="sourceLineNo">425</span><a name="line.425"></a>
+<span class="sourceLineNo">426</span>  public long getFreeSize() {<a name="line.426"></a>
+<span class="sourceLineNo">427</span>    return this.totalSize - getUsedSize();<a name="line.427"></a>
+<span class="sourceLineNo">428</span>  }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>  public long getTotalSize() {<a name="line.430"></a>
+<span class="sourceLineNo">431</span>    return this.totalSize;<a name="line.431"></a>
+<span class="sourceLineNo">432</span>  }<a name="line.432"></a>
+<span class="sourceLineNo">433</span><a name="line.433"></a>
+<span class="sourceLineNo">434</span>  /**<a name="line.434"></a>
+<span class="sourceLineNo">435</span>   * Allocate a block with specified size. Return the offset<a name="line.435"></a>
+<span class="sourceLineNo">436</span>   * @param blockSize size of block<a name="line.436"></a>
+<span class="sourceLineNo">437</span>   * @throws BucketAllocatorException<a name="line.437"></a>
+<span class="sourceLineNo">438</span>   * @throws CacheFullException<a name="line.438"></a>
+<span class="sourceLineNo">439</span>   * @return the offset in the IOEngine<a name="line.439"></a>
+<span class="sourceLineNo">440</span>   */<a name="line.440"></a>
+<span class="sourceLineNo">441</span>  public synchronized long allocateBlock(int blockSize) throws CacheFullException,<a name="line.441"></a>
+<span class="sourceLineNo">442</span>      BucketAllocatorException {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>    assert blockSize &gt; 0;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>    BucketSizeInfo bsi = roundUpToBucketSizeInfo(blockSize);<a name="line.444"></a>
+<span class="sourceLineNo">445</span>    if (bsi == null) {<a name="line.445"></a>
+<span class="sourceLineNo">446</span>      throw new BucketAllocatorException("Allocation too big size=" + blockSize +<a name="line.446"></a>
+<span class="sourceLineNo">447</span>        "; adjust BucketCache sizes " + BlockCacheFactory.BUCKET_CACHE_BUCKETS_KEY +<a name="line.447"></a>
+<span class="sourceLineNo">448</span>        " to accomodate if size seems reasonable and you want it cached.");<a name="line.448"></a>
+<span class="sourceLineNo">449</span>    }<a name="line.449"></a>
+<span class="sourceLineNo">450</span>    long offset = bsi.allocateBlock();<a name="line.450"></a>
+<span class="sourceLineNo">451</span><a name="line.451"></a>
+<span class="sourceLineNo">452</span>    // Ask caller to free up space and try again!<a name="line.452"></a>
+<span class="sourceLineNo">453</span>    if (offset &lt; 0)<a name="line.453"></a>
+<span class="sourceLineNo">454</span>      throw new CacheFullException(blockSize, bsi.sizeIndex());<a name="line.454"></a>
+<span class="sourceLineNo">455</span>    usedSize += bucketSizes[bsi.sizeIndex()];<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    return offset;<a name="line.456"></a>
+<span class="sourceLineNo">457</span>  }<a name="line.457"></a>
+<span class="sourceLineNo">458</span><a name="line.458"></a>
+<span class="sourceLineNo">459</span>  private Bucket grabGlobalCompletelyFreeBucket() {<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    for (BucketSizeInfo bsi : bucketSizeInfos) {<a name="line.460"></a>
+<span class="sourceLineNo">461</span>      Bucket b = bsi.findAndRemoveCompletelyFreeBucket();<a name="line.461"></a>
+<span class="sourceLineNo">462</span>      if (b != null) return b;<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    }<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    return null;<a name="line.464"></a>
+<span class="sourceLineNo">465</span>  }<a name="line.465"></a>
+<span class="sourceLineNo">466</span><a name="line.466"></a>
+<span class="sourceLineNo">467</span>  /**<a name="line.467"></a>
+<span class="sourceLineNo">468</span>   * Free a block with the offset<a name="line.468"></a>
+<span class="sourceLineNo">469</span>   * @param offset block's offset<a name="line.469"></a>
+<span class="sourceLineNo">470</span>   * @return size freed<a name="line.470"></a>
+<span class="sourceLineNo">471</span>   */<a name="line.471"></a>
+<span class="sourceLineNo">472</span>  public synchronized int freeBlock(long offset) {<a name="line.472"></a>
+<span class="sourceLineNo">473</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.473"></a>
+<span class="sourceLineNo">474</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.474"></a>
+<span class="sourceLineNo">475</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.475"></a>
+<span class="sourceLineNo">476</span>    bucketSizeInfos[targetBucket.sizeIndex()].freeBlock(targetBucket, offset);<a name="line.476"></a>
+<span class="sourceLineNo">477</span>    usedSize -= targetBucket.getItemAllocationSize();<a name="line.477"></a>
+<span class="sourceLineNo">478</span>    return targetBucket.getItemAllocationSize();<a name="line.478"></a>
+<span class="sourceLineNo">479</span>  }<a name="line.479"></a>
+<span class="sourceLineNo">480</span><a name="line.480"></a>
+<span class="sourceLineNo">481</span>  public int sizeIndexOfAllocation(long offset) {<a name="line.481"></a>
+<span class="sourceLineNo">482</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.482"></a>
+<span class="sourceLineNo">483</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.483"></a>
+<span class="sourceLineNo">484</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.484"></a>
+<span class="sourceLineNo">485</span>    return targetBucket.sizeIndex();<a name="line.485"></a>
+<span class="sourceLineNo">486</span>  }<a name="line.486"></a>
+<span class="sourceLineNo">487</span><a name="line.487"></a>
+<span class="sourceLineNo">488</span>  public int sizeOfAllocation(long offset) {<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    int bucketNo = (int) (offset / bucketCapacity);<a name="line.489"></a>
+<span class="sourceLineNo">490</span>    assert bucketNo &gt;= 0 &amp;&amp; bucketNo &lt; buckets.length;<a name="line.490"></a>
+<span class="sourceLineNo">491</span>    Bucket targetBucket = buckets[bucketNo];<a name="line.491"></a>
+<span class="sourceLineNo">492</span>    return targetBucket.getItemAllocationSize();<a name="line.492"></a>
+<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
+<span class="sourceLineNo">494</span><a name="line.494"></a>
+<span class="sourceLineNo">495</span>  static class IndexStatistics {<a name="line.495"></a>
+<span class="sourceLineNo">496</span>    private long freeCount, usedCount, itemSize, totalCount;<a name="line.496"></a>
+<span class="sourceLineNo">497</span><a name="line.497"></a>
+<span class="sourceLineNo">498</span>    public long freeCount() {<a name="line.498"></a>
+<span class="sourceLineNo">499</span>      return freeCount;<a name="line.499"></a>
+<span class="sourceLineNo">500</span>    }<a name="line.500"></a>
+<span class="sourceLineNo">501</span><a name="line.501"></a>
+<span class="sourceLineNo">502</span>    public long usedCount() {<a name="line.502"></a>
+<span class="sourceLineNo">503</span>      return usedCount;<a name="line.503"></a>
+<span class="sourceLineNo">504</span>    }<a name="line.504"></a>
+<span class="sourceLineNo">505</span><a name="line.505"></a>
+<span class="sourceLineNo">506</span>    public long totalCount() {<a name="line.506"></a>
+<span class="sourceLineNo">507</span>      return totalCount;<a name="line.507"></a>
+<span class="sourceLineNo">508</span>    }<a name="line.508"></a>
+<span class="sourceLineNo">509</span><a name="line.509"></a>
+<span class="sourceLineNo">510</span>    public long freeBytes() {<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      return freeCount * itemSize;<a name="line.511"></a>
+<span class="sourceLineNo">512</span>    }<a name="line.512"></a>
+<span class="sourceLineNo">513</span><a name="line.513"></a>
+<span class="sourceLineNo">514</span>    public long usedBytes() {<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      return usedCount * itemSize;<a name="line.515"></a>
+<span class="sourceLineNo">516</span>    }<a name="line.516"></a>
+<span class="sourceLineNo">517</span><a name="line.517"></a>
+<span class="sourceLineNo">518</span>    public long totalBytes() {<a name="line.518"></a>
+<span class="sourceLineNo">519</span>      return totalCount * itemSize;<a name="line.519"></a>
+<span class="sourceLineNo">520</span>    }<a name="line.520"></a>
+<span class="sourceLineNo">521</span><a name="line.521"></a>
+<span class="sourceLineNo">522</span>    public long itemSize() {<a name="line.522"></a>
+<span class="sourceLineNo">523</span>      return itemSize;<a name="line.523"></a>
+<span class="sourceLineNo">524</span>    }<a name="line.524"></a>
+<span class="sourceLineNo">525</span><a name="line.525"></a>
+<span class="sourceLineNo">526</span>    public IndexStatistics(long free, long used, long itemSize) {<a name="line.526"></a>
+<span class="sourceLineNo">527</span>      setTo(free, used, itemSize);<a name="line.527"></a>
+<span class="sourceLineNo">528</span>    }<a name="line.528"></a>
+<span class="sourceLineNo">529</span><a name="line.529"></a>
+<span class="sourceLineNo">530</span>    public IndexStatistics() {<a name="line.530"></a>
+<span class="sourceLineNo">531</span>      setTo(-1, -1, 0);<a name="line.531"></a>
+<span class="sourceLineNo">532</span>    }<a name="line.532"></a>
+<span class="sourceLineNo">533</span><a name="line.533"></a>
+<span class="sourceLineNo">534</span>    public void setTo(long free, long used, long itemSize) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>      this.itemSize = itemSize;<a name="line.535"></a>
+<span class="sourceLineNo">536</span>      this.freeCount = free;<a name="line.536"></a>
+<span class="sourceLineNo">537</span>      this.usedCount = used;<a name="line.537"></a>
+<span class="sourceLineNo">538</span>      this.totalCount = free + used;<a name="line.538"></a>
+<span class="sourceLineNo">539</span>    }<a name="line.539"></a>
+<span class="sourceLineNo">540</span>  }<a name="line.540"></a>
+<span class="sourceLineNo">541</span><a name="line.541"></a>
+<span class="sourceLineNo">542</span>  public Bucket [] getBuckets() {<a name="line.542"></a>
+<span class="sourceLineNo">543</span>    return this.buckets;<a name="line.543"></a>
+<span class="sourceLineNo">544</span>  }<a name="line.544"></a>
+<span class="sourceLineNo">545</span><a name="line.545"></a>
+<span class="sourceLineNo">546</span>  void logStatistics() {<a name="line.546"></a>
+<span class="sourceLineNo">547</span>    IndexStatistics total = new IndexStatistics();<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    IndexStatistics[] stats = getIndexStatistics(total);<a name="line.548"></a>
+<span class="sourceLineNo">549</span>    LOG.info("Bucket allocator statistics follow:\n");<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    LOG.info("  Free bytes=" + total.freeBytes() + "+; used bytes="<a name="line.550"></a>
+<span class="sourceLineNo">551</span>        + total.usedBytes() + "; total bytes=" + total.totalBytes());<a name="line.551"></a>
+<span class="sourceLineNo">552</span>    for (IndexStatistics s : stats) {<a name="line.552"></a>
+<span class="sourceLineNo">553</span>      LOG.info("  Object size " + s.itemSize() + " used=" + s.usedCount()<a name="line.553"></a>
+<span class="sourceLineNo">554</span>          + "; free=" + s.freeCount() + "; total=" + s.totalCount());<a name="line.554"></a>
+<span class="sourceLineNo">555</span>    }<a name="line.555"></a>
+<span class="sourceLineNo">556</span>  }<a name="line.556"></a>
+<span class="sourceLineNo">557</span><a name="line.557"></a>
+<span class="sourceLineNo">558</span>  IndexStatistics[] getIndexStatistics(IndexStatistics grandTotal) {<a name="line.558"></a>
+<span class="sourceLineNo">559</span>    IndexStatistics[] stats = getIndexStatistics();<a name="line.559"></a>
+<span class="sourceLineNo">560</span>    long totalfree = 0, totalused = 0;<a name="line.560"></a>
+<span class="sourceLineNo">561</span>    for (IndexStatistics stat : stats) {<a name="line.561"></a>
+<span class="sourceLineNo">562</span>      totalfree += stat.freeBytes();<a name="line.562"></a>
+<span class="sourceLineNo">563</span>      totalused += stat.usedBytes();<a name="line.563"></a>
+<span class="sourceLineNo">564</span>    }<a name="line.564"></a>
+<span class="sourceLineNo">565</span>    grandTotal.setTo(totalfree, totalused, 1);<a name="line.565"></a>
+<span class="sourceLineNo">566</span>    return stats;<a name="line.566"></a>
+<span class="sourceLineNo">567</span>  }<a name="line.567"></a>
+<span class="sourceLineNo">568</span><a name="line.568"></a>
+<span class="sourceLineNo">569</span>  IndexStatistics[] getIndexStatistics() {<a name="line.569"></a>
+<span class="sourceLineNo">570</span>    IndexStatistics[] stats = new IndexStatistics[bucketSizes.length];<a name="line.570"></a>
+<span class="sourceLineNo">571</span>    for (int i = 0; i &lt; stats.length; ++i)<a name="line.571"></a>
+<span class="sourceLineNo">572</span>      stats[i] = bucketSizeInfos[i].statistics();<a name="line.572"></a>
+<span class="sourceLineNo">573</span>    return stats;<a name="line.573"></a>
+<span class="sourceLineNo">574</span>  }<a name="line.574"></a>
+<span class="sourceLineNo">575</span><a name="line.575"></a>
+<span class="sourceLineNo">576</span>  public long freeBlock(long freeList[]) {<a name="line.576"></a>
+<span class="sourceLineNo">577</span>    long sz = 0;<a name="line.577"></a>
+<span class="sourceLineNo">578</span>    for (int i = 0; i &lt; freeList.length; ++i)<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      sz += freeBlock(freeList[i]);<a name="line.579"></a>
+<span class="sourceLineNo">580</span>    return sz;<a name="line.580"></a>
+<span class="sourceLineNo">581</span>  }<a name="line.581"></a>
+<span class="sourceLineNo">582</span><a name="line.582"></a>
+<span class="sourceLineNo">583</span>  public int getBucketIndex(long offset) {<a name="line.583"></a>
+<span class="sourceLineNo">584</span>    return (int) (offset / bucketCapacity);<a name="line.584"></a>
+<span class="sourceLineNo">585</span>  }<a name="line.585"></a>
+<span class="sourceLineNo">586</span><a name="line.586"></a>
+<span class="sourceLineNo">587</span>  /**<a name="line.587"></a>
+<span class="sourceLineNo">588</span>   * Returns a set of indices of the buckets that are least filled<a name="line.588"></a>
+<span class="sourceLineNo">589</span>   * excluding the offsets, we also the fully free buckets for the<a name="line.589"></a>
+<span class="sourceLineNo">590</span>   * BucketSizes where everything is empty and they only have one<a name="line.590"></a>
+<span class="sourceLineNo">591</span>   * completely free bucket as a reserved<a name="line.591"></a>
+<span class="sourceLineNo">592</span>   *<a name="line.592"></a>
+<span class="sourceLineNo">593</span>   * @param excludedBuckets the buckets that need to be excluded due to<a name="line.593"></a>
+<span class="sourceLineNo">594</span>   *                        currently being in used<a name="line.594"></a>
+<span class="sourceLineNo">595</span>   * @param bucketCount     max Number of buckets to return<a name="line.595"></a>
+<span class="sourceLineNo">596</span>   * @return set of bucket indices which could be used for eviction<a name="line.596"></a>
+<span class="sourceLineNo">597</span>   */<a name="line.597"></a>
+<span class="sourceLineNo">598</span>  public Set&lt;Integer&gt; getLeastFilledBuckets(Set&lt;Integer&gt; excludedBuckets,<a name="line.598"></a>
+<span class="sourceLineNo">599</span>                                            int bucketCount) {<a name="line.599"></a>
+<span class="sourceLineNo">600</span>    Queue&lt;Integer&gt; queue = MinMaxPriorityQueue.&lt;Integer&gt;orderedBy(<a name="line.600"></a>
+<span class="sourceLineNo">601</span>        new Comparator&lt;Integer&gt;() {<a name="line.601"></a>
+<span class="sourceLineNo">602</span>          @Override<a name="line.602"></a>
+<span class="sourceLineNo">603</span>          public int compare(Integer left, Integer right) {<a name="line.603"></a>
+<span class="sourceLineNo">604</span>            // We will always get instantiated buckets<a name="line.604"></a>
+<span class="sourceLineNo">605</span>            return Float.compare(<a name="line.605"></a>
+<span class="sourceLineNo">606</span>                ((float) buckets[left].usedCount) / buckets[left].itemCount,<a name="line.606"></a>
+<span class="sourceLineNo">607</span>                ((float) buckets[right].usedCount) / buckets[right].itemCount);<a name="line.607"></a>
+<span class="sourceLineNo">608</span>          }<a name="line.608"></a>
+<span class="sourceLineNo">609</span>        }).maximumSize(bucketCount).create();<a name="line.609"></a>
+<span class="sourceLineNo">610</span><a name="line.610"></a>
+<span class="sourceLineNo">611</span>    for (int i = 0; i &lt; buckets.length; i ++ ) {<a name="line.611"></a>
+<span class="sourceLineNo">612</span>      if (!excludedBuckets.contains(i) &amp;&amp; !buckets[i].isUninstantiated() &amp;&amp;<a name="line.612"></a>
+<span class="sourceLineNo">613</span>          // Avoid the buckets that are the only buckets for a sizeIndex<a name="line.613"></a>
+<span class="sourceLineNo">614</span>          bucketSizeInfos[buckets[i].sizeIndex()].bucketList.size() != 1) {<a name="line.614"></a>
+<span class="sourceLineNo">615</span>        queue.add(i);<a name="line.615"></a>
+<span class="sourceLineNo">616</span>      }<a name="line.616"></a>
+<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
+<span class="sourceLineNo">618</span><a name="line.618"></a>
+<span class="sourceLineNo">619</span>    Set&lt;Integer&gt; result = new HashSet&lt;&gt;(bucketCount);<a name="line.619"></a>
+<span class="sourceLineNo">620</span>    result.addAll(queue);<a name="line.620"></a>
+<span class="sourceLineNo">621</span><a name="line.621"></a>
+<span class="sourceLineNo">622</span>    return result;<a name="line.622"></a>
+<span class="sourceLineNo">623</span>  }<a name="line.623"></a>
+<span class="sourceLineNo">624</span>}<a name="line.624"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html b/devapidocs/src-html/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html
index 3189932..7e4176b 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/security/AbstractHBaseSaslRpcClient.html
@@ -97,38 +97,32 @@
 <span class="sourceLineNo">089</span>  }<a name="line.89"></a>
 <span class="sourceLineNo">090</span><a name="line.90"></a>
 <span class="sourceLineNo">091</span>  /**<a name="line.91"></a>
-<span class="sourceLineNo">092</span>   * Computes the initial response a client sends to a server to begin the SASL<a name="line.92"></a>
-<span class="sourceLineNo">093</span>   * challenge/response handshake. If the client's SASL mechanism does not require<a name="line.93"></a>
-<span class="sourceLineNo">094</span>   * that an initial response is sent to begin the handshake, this method will return<a name="line.94"></a>
-<span class="sourceLineNo">095</span>   * a null byte array, indicating no initial response needs to be sent by this client.<a name="line.95"></a>
-<span class="sourceLineNo">096</span>   *<a name="line.96"></a>
-<span class="sourceLineNo">097</span>   * It is unclear as to whether all SASL implementations will return a non-empty initial<a name="line.97"></a>
-<span class="sourceLineNo">098</span>   * response, so this implementation is written such that this is allowed. All known<a name="line.98"></a>
-<span class="sourceLineNo">099</span>   * SASL mechanism implementations in the JDK provide non-empty initial responses.<a name="line.99"></a>
-<span class="sourceLineNo">100</span>   *<a name="line.100"></a>
-<span class="sourceLineNo">101</span>   * @return The client's initial response to send the server (which may be empty), or null<a name="line.101"></a>
-<span class="sourceLineNo">102</span>   *    if this implementation does not require an initial response to be sent.<a name="line.102"></a>
-<span class="sourceLineNo">103</span>   */<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  public byte[] getInitialResponse() throws SaslException {<a name="line.104"></a>
-<span class="sourceLineNo">105</span>    if (saslClient.hasInitialResponse()) {<a name="line.105"></a>
-<span class="sourceLineNo">106</span>      return saslClient.evaluateChallenge(EMPTY_TOKEN);<a name="line.106"></a>
-<span class="sourceLineNo">107</span>    }<a name="line.107"></a>
-<span class="sourceLineNo">108</span>    return null;<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  }<a name="line.109"></a>
-<span class="sourceLineNo">110</span><a name="line.110"></a>
-<span class="sourceLineNo">111</span>  public boolean isComplete() {<a name="line.111"></a>
-<span class="sourceLineNo">112</span>    return saslClient.isComplete();<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>  public byte[] evaluateChallenge(byte[] challenge) throws SaslException {<a name="line.115"></a>
-<span class="sourceLineNo">116</span>    return saslClient.evaluateChallenge(challenge);<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>  /** Release resources used by wrapped saslClient */<a name="line.119"></a>
-<span class="sourceLineNo">120</span>  public void dispose() {<a name="line.120"></a>
-<span class="sourceLineNo">121</span>    SaslUtil.safeDispose(saslClient);<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">092</span>   * Computes the initial response a client sends to a server to begin the SASL challenge/response<a name="line.92"></a>
+<span class="sourceLineNo">093</span>   * handshake. If the client's SASL mechanism does not have an initial response, an empty token<a name="line.93"></a>
+<span class="sourceLineNo">094</span>   * will be returned without querying the evaluateChallenge method, as an authentication processing<a name="line.94"></a>
+<span class="sourceLineNo">095</span>   * must be started by client.<a name="line.95"></a>
+<span class="sourceLineNo">096</span>   * @return The client's initial response to send the server (which may be empty).<a name="line.96"></a>
+<span class="sourceLineNo">097</span>   */<a name="line.97"></a>
+<span class="sourceLineNo">098</span>  public byte[] getInitialResponse() throws SaslException {<a name="line.98"></a>
+<span class="sourceLineNo">099</span>    if (saslClient.hasInitialResponse()) {<a name="line.99"></a>
+<span class="sourceLineNo">100</span>      return saslClient.evaluateChallenge(EMPTY_TOKEN);<a name="line.100"></a>
+<span class="sourceLineNo">101</span>    }<a name="line.101"></a>
+<span class="sourceLineNo">102</span>    return EMPTY_TOKEN;<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  }<a name="line.103"></a>
+<span class="sourceLineNo">104</span><a name="line.104"></a>
+<span class="sourceLineNo">105</span>  public boolean isComplete() {<a name="line.105"></a>
+<span class="sourceLineNo">106</span>    return saslClient.isComplete();<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>  public byte[] evaluateChallenge(byte[] challenge) throws SaslException {<a name="line.109"></a>
+<span class="sourceLineNo">110</span>    return saslClient.evaluateChallenge(challenge);<a name="line.110"></a>
+<span class="sourceLineNo">111</span>  }<a name="line.111"></a>
+<span class="sourceLineNo">112</span><a name="line.112"></a>
+<span class="sourceLineNo">113</span>  /** Release resources used by wrapped saslClient */<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  public void dispose() {<a name="line.114"></a>
+<span class="sourceLineNo">115</span>    SaslUtil.safeDispose(saslClient);<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>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.html b/devapidocs/src-html/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.html
index de09133..a8bf835 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.html
@@ -127,71 +127,69 @@
 <span class="sourceLineNo">119</span>          return saslRpcClient.getInitialResponse();<a name="line.119"></a>
 <span class="sourceLineNo">120</span>        }<a name="line.120"></a>
 <span class="sourceLineNo">121</span>      });<a name="line.121"></a>
-<span class="sourceLineNo">122</span>      if (initialResponse != null) {<a name="line.122"></a>
-<span class="sourceLineNo">123</span>        writeResponse(ctx, initialResponse);<a name="line.123"></a>
-<span class="sourceLineNo">124</span>      } else {<a name="line.124"></a>
-<span class="sourceLineNo">125</span>        LOG.trace("SASL initialResponse was null, not sending response to server.");<a name="line.125"></a>
-<span class="sourceLineNo">126</span>      }<a name="line.126"></a>
-<span class="sourceLineNo">127</span>      // HBASE-23881 We do not want to check if the SaslClient thinks the handshake is<a name="line.127"></a>
-<span class="sourceLineNo">128</span>      // complete as, at this point, we've not heard a back from the server with it's reply<a name="line.128"></a>
-<span class="sourceLineNo">129</span>      // to our first challenge response. We should wait for at least one reply<a name="line.129"></a>
-<span class="sourceLineNo">130</span>      // from the server before calling negotiation complete.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>      //<a name="line.131"></a>
-<span class="sourceLineNo">132</span>      // Each SASL mechanism has its own handshake. Some mechanisms calculate a single client buffer<a name="line.132"></a>
-<span class="sourceLineNo">133</span>      // to be sent to the server while others have multiple exchanges to negotiate authentication. GSSAPI(Kerberos)<a name="line.133"></a>
-<span class="sourceLineNo">134</span>      // and DIGEST-MD5 both are examples of mechanisms which have multiple steps. Mechanisms which have multiple steps<a name="line.134"></a>
-<span class="sourceLineNo">135</span>      // will not return true on `SaslClient#isComplete()` until the handshake has fully completed. Mechanisms which<a name="line.135"></a>
-<span class="sourceLineNo">136</span>      // only send a single buffer may return true on `isComplete()` after that initial response is calculated.<a name="line.136"></a>
-<span class="sourceLineNo">137</span>    } catch (Exception e) {<a name="line.137"></a>
-<span class="sourceLineNo">138</span>      // the exception thrown by handlerAdded will not be passed to the exceptionCaught below<a name="line.138"></a>
-<span class="sourceLineNo">139</span>      // because netty will remove a handler if handlerAdded throws an exception.<a name="line.139"></a>
-<span class="sourceLineNo">140</span>      exceptionCaught(ctx, e);<a name="line.140"></a>
-<span class="sourceLineNo">141</span>    }<a name="line.141"></a>
-<span class="sourceLineNo">142</span>  }<a name="line.142"></a>
-<span class="sourceLineNo">143</span><a name="line.143"></a>
-<span class="sourceLineNo">144</span>  @Override<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {<a name="line.145"></a>
-<span class="sourceLineNo">146</span>    int len = msg.readInt();<a name="line.146"></a>
-<span class="sourceLineNo">147</span>    if (len == SaslUtil.SWITCH_TO_SIMPLE_AUTH) {<a name="line.147"></a>
-<span class="sourceLineNo">148</span>      saslRpcClient.dispose();<a name="line.148"></a>
-<span class="sourceLineNo">149</span>      if (saslRpcClient.fallbackAllowed) {<a name="line.149"></a>
-<span class="sourceLineNo">150</span>        saslPromise.trySuccess(false);<a name="line.150"></a>
-<span class="sourceLineNo">151</span>      } else {<a name="line.151"></a>
-<span class="sourceLineNo">152</span>        saslPromise.tryFailure(new FallbackDisallowedException());<a name="line.152"></a>
-<span class="sourceLineNo">153</span>      }<a name="line.153"></a>
-<span class="sourceLineNo">154</span>      return;<a name="line.154"></a>
-<span class="sourceLineNo">155</span>    }<a name="line.155"></a>
-<span class="sourceLineNo">156</span>    LOG.trace("Reading input token size={} for processing by initSASLContext", len);<a name="line.156"></a>
-<span class="sourceLineNo">157</span>    final byte[] challenge = new byte[len];<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    msg.readBytes(challenge);<a name="line.158"></a>
-<span class="sourceLineNo">159</span>    byte[] response = ugi.doAs(new PrivilegedExceptionAction&lt;byte[]&gt;() {<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>      @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>      public byte[] run() throws Exception {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>        return saslRpcClient.evaluateChallenge(challenge);<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>    if (response != null) {<a name="line.166"></a>
-<span class="sourceLineNo">167</span>      writeResponse(ctx, response);<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    } else {<a name="line.168"></a>
-<span class="sourceLineNo">169</span>      LOG.trace("SASL challenge response was empty, not sending response to server.");<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    }<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    tryComplete(ctx);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>  }<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>  @Override<a name="line.174"></a>
-<span class="sourceLineNo">175</span>  public void channelInactive(ChannelHandlerContext ctx) throws Exception {<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    saslRpcClient.dispose();<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    saslPromise.tryFailure(new ConnectionClosedException("Connection closed"));<a name="line.177"></a>
-<span class="sourceLineNo">178</span>    ctx.fireChannelInactive();<a name="line.178"></a>
-<span class="sourceLineNo">179</span>  }<a name="line.179"></a>
-<span class="sourceLineNo">180</span><a name="line.180"></a>
-<span class="sourceLineNo">181</span>  @Override<a name="line.181"></a>
-<span class="sourceLineNo">182</span>  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {<a name="line.182"></a>
-<span class="sourceLineNo">183</span>    saslRpcClient.dispose();<a name="line.183"></a>
-<span class="sourceLineNo">184</span>    saslPromise.tryFailure(cause);<a name="line.184"></a>
-<span class="sourceLineNo">185</span>  }<a name="line.185"></a>
-<span class="sourceLineNo">186</span>}<a name="line.186"></a>
+<span class="sourceLineNo">122</span>      assert initialResponse != null;<a name="line.122"></a>
+<span class="sourceLineNo">123</span>      writeResponse(ctx, initialResponse);<a name="line.123"></a>
+<span class="sourceLineNo">124</span>      // HBASE-23881 We do not want to check if the SaslClient thinks the handshake is<a name="line.124"></a>
+<span class="sourceLineNo">125</span>      // complete as, at this point, we've not heard a back from the server with it's reply<a name="line.125"></a>
+<span class="sourceLineNo">126</span>      // to our first challenge response. We should wait for at least one reply<a name="line.126"></a>
+<span class="sourceLineNo">127</span>      // from the server before calling negotiation complete.<a name="line.127"></a>
+<span class="sourceLineNo">128</span>      //<a name="line.128"></a>
+<span class="sourceLineNo">129</span>      // Each SASL mechanism has its own handshake. Some mechanisms calculate a single client buffer<a name="line.129"></a>
+<span class="sourceLineNo">130</span>      // to be sent to the server while others have multiple exchanges to negotiate authentication.<a name="line.130"></a>
+<span class="sourceLineNo">131</span>      // GSSAPI(Kerberos) and DIGEST-MD5 both are examples of mechanisms which have multiple steps.<a name="line.131"></a>
+<span class="sourceLineNo">132</span>      // Mechanisms which have multiple steps will not return true on `SaslClient#isComplete()`<a name="line.132"></a>
+<span class="sourceLineNo">133</span>      // until the handshake has fully completed. Mechanisms which only send a single buffer may<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      // return true on `isComplete()` after that initial response is calculated.<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    } catch (Exception e) {<a name="line.135"></a>
+<span class="sourceLineNo">136</span>      // the exception thrown by handlerAdded will not be passed to the exceptionCaught below<a name="line.136"></a>
+<span class="sourceLineNo">137</span>      // because netty will remove a handler if handlerAdded throws an exception.<a name="line.137"></a>
+<span class="sourceLineNo">138</span>      exceptionCaught(ctx, e);<a name="line.138"></a>
+<span class="sourceLineNo">139</span>    }<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  }<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  @Override<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {<a name="line.143"></a>
+<span class="sourceLineNo">144</span>    int len = msg.readInt();<a name="line.144"></a>
+<span class="sourceLineNo">145</span>    if (len == SaslUtil.SWITCH_TO_SIMPLE_AUTH) {<a name="line.145"></a>
+<span class="sourceLineNo">146</span>      saslRpcClient.dispose();<a name="line.146"></a>
+<span class="sourceLineNo">147</span>      if (saslRpcClient.fallbackAllowed) {<a name="line.147"></a>
+<span class="sourceLineNo">148</span>        saslPromise.trySuccess(false);<a name="line.148"></a>
+<span class="sourceLineNo">149</span>      } else {<a name="line.149"></a>
+<span class="sourceLineNo">150</span>        saslPromise.tryFailure(new FallbackDisallowedException());<a name="line.150"></a>
+<span class="sourceLineNo">151</span>      }<a name="line.151"></a>
+<span class="sourceLineNo">152</span>      return;<a name="line.152"></a>
+<span class="sourceLineNo">153</span>    }<a name="line.153"></a>
+<span class="sourceLineNo">154</span>    LOG.trace("Reading input token size={} for processing by initSASLContext", len);<a name="line.154"></a>
+<span class="sourceLineNo">155</span>    final byte[] challenge = new byte[len];<a name="line.155"></a>
+<span class="sourceLineNo">156</span>    msg.readBytes(challenge);<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    byte[] response = ugi.doAs(new PrivilegedExceptionAction&lt;byte[]&gt;() {<a name="line.157"></a>
+<span class="sourceLineNo">158</span><a name="line.158"></a>
+<span class="sourceLineNo">159</span>      @Override<a name="line.159"></a>
+<span class="sourceLineNo">160</span>      public byte[] run() throws Exception {<a name="line.160"></a>
+<span class="sourceLineNo">161</span>        return saslRpcClient.evaluateChallenge(challenge);<a name="line.161"></a>
+<span class="sourceLineNo">162</span>      }<a name="line.162"></a>
+<span class="sourceLineNo">163</span>    });<a name="line.163"></a>
+<span class="sourceLineNo">164</span>    if (response != null) {<a name="line.164"></a>
+<span class="sourceLineNo">165</span>      writeResponse(ctx, response);<a name="line.165"></a>
+<span class="sourceLineNo">166</span>    } else {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>      LOG.trace("SASL challenge response was empty, not sending response to server.");<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    }<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    tryComplete(ctx);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>  }<a name="line.170"></a>
+<span class="sourceLineNo">171</span><a name="line.171"></a>
+<span class="sourceLineNo">172</span>  @Override<a name="line.172"></a>
+<span class="sourceLineNo">173</span>  public void channelInactive(ChannelHandlerContext ctx) throws Exception {<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    saslRpcClient.dispose();<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    saslPromise.tryFailure(new ConnectionClosedException("Connection closed"));<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    ctx.fireChannelInactive();<a name="line.176"></a>
+<span class="sourceLineNo">177</span>  }<a name="line.177"></a>
+<span class="sourceLineNo">178</span><a name="line.178"></a>
+<span class="sourceLineNo">179</span>  @Override<a name="line.179"></a>
+<span class="sourceLineNo">180</span>  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {<a name="line.180"></a>
+<span class="sourceLineNo">181</span>    saslRpcClient.dispose();<a name="line.181"></a>
+<span class="sourceLineNo">182</span>    saslPromise.tryFailure(cause);<a name="line.182"></a>
+<span class="sourceLineNo">183</span>  }<a name="line.183"></a>
+<span class="sourceLineNo">184</span>}<a name="line.184"></a>
 
 
 
diff --git a/downloads.html b/downloads.html
index 627fba2..1ca1d70 100644
--- a/downloads.html
+++ b/downloads.html
@@ -465,7 +465,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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 562b268..7b4382b 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 c8eb3d6..f51a117 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 24be858..a6425f4 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 7443c24..c007552 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 d24d72f..9014ee5 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 459654c..61012fc 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 f2a786b..597d850 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 51b020c..09167cd 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 343d8c4..7f5cf63 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 dc4e25f..7e84730 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 14ec730..250e47a 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 c049c05..07367de 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 ebe3c10..99d1b0b 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 6c869b0..f666245 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 93a8b7f..c8c5959 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 64c980f..e73297f 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 0728939..59c125a 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 efc562d..9a6e0fc 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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 af45236..0e94b87 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-04-25</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2020-04-26</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>