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 2026/02/26 14:52:31 UTC

(hbase-site) branch asf-site updated: Published site at 01f93dbf6add6223851a0482842f4253e53b966f.

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 da5b562cf34 Published site at 01f93dbf6add6223851a0482842f4253e53b966f.
da5b562cf34 is described below

commit da5b562cf34ee7434b9fcc5072600f6297fd68eb
Author: jenkins <bu...@apache.org>
AuthorDate: Thu Feb 26 14:52:22 2026 +0000

    Published site at 01f93dbf6add6223851a0482842f4253e53b966f.
---
 apache_hbase_reference_guide.pdf                   |   4 +-
 .../hadoop/hbase/regionserver/StoreScanner.html    | 726 ++++++++++-----------
 book.html                                          |   2 +-
 checkstyle-aggregate.html                          |   8 +-
 dependency-convergence.html                        |   2 +-
 dependency-info.html                               |   2 +-
 dependency-management.html                         |   2 +-
 .../hadoop/hbase/regionserver/StoreScanner.html    |  44 +-
 .../hadoop/hbase/regionserver/StoreScanner.html    | 726 ++++++++++-----------
 hbase-website/dependency-convergence.html          |   2 +-
 hbase-website/dependency-info.html                 |   2 +-
 hbase-website/dependency-management.html           |   2 +-
 hbase-website/index.html                           |   2 +-
 hbase-website/issue-management.html                |   2 +-
 hbase-website/licenses.html                        |   2 +-
 hbase-website/mailing-lists.html                   |   2 +-
 hbase-website/plugin-management.html               |   2 +-
 hbase-website/plugins.html                         |   2 +-
 hbase-website/project-info.html                    |   2 +-
 hbase-website/scm.html                             |   2 +-
 hbase-website/summary.html                         |   2 +-
 hbase-website/team.html                            |   2 +-
 issue-management.html                              |   2 +-
 licenses.html                                      |   2 +-
 mailing-lists.html                                 |   2 +-
 plugin-management.html                             |   2 +-
 plugins.html                                       |   2 +-
 project-info.html                                  |   2 +-
 project-reports.html                               |   2 +-
 scm.html                                           |   2 +-
 summary.html                                       |   2 +-
 team.html                                          |   2 +-
 32 files changed, 779 insertions(+), 783 deletions(-)

diff --git a/apache_hbase_reference_guide.pdf b/apache_hbase_reference_guide.pdf
index 03bff025a2a..517746989b3 100644
--- a/apache_hbase_reference_guide.pdf
+++ b/apache_hbase_reference_guide.pdf
@@ -5,8 +5,8 @@
 /Author (Apache HBase Team)
 /Creator (Asciidoctor PDF 2.0.6, based on Prawn 2.4.0)
 /Producer (Apache HBase Team)
-/ModDate (D:20260225143129+00'00')
-/CreationDate (D:20260225144748+00'00')
+/ModDate (D:20260226143122+00'00')
+/CreationDate (D:20260226144709+00'00')
 >>
 endobj
 2 0 obj
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html b/apidocs/src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html
index 4bcf5fa6220..3c845fd720d 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html
@@ -977,370 +977,368 @@
 <span class="source-line-no">964</span><span id="line-964">    } while ((nextCell = this.heap.peek()) != null &amp;&amp; CellUtil.matchingRowColumn(cell, nextCell));</span>
 <span class="source-line-no">965</span><span id="line-965">    // We need this check because it may happen that the new scanner that we get</span>
 <span class="source-line-no">966</span><span id="line-966">    // during heap.next() is requiring reseek due of fake KV previously generated for</span>
-<span class="source-line-no">967</span><span id="line-967">    // ROWCOL bloom filter optimization. See HBASE-19863 for more details</span>
-<span class="source-line-no">968</span><span id="line-968">    if (</span>
-<span class="source-line-no">969</span><span id="line-969">      useRowColBloom &amp;&amp; nextCell != null &amp;&amp; cell.getTimestamp() == PrivateConstants.OLDEST_TIMESTAMP</span>
-<span class="source-line-no">970</span><span id="line-970">    ) {</span>
-<span class="source-line-no">971</span><span id="line-971">      return false;</span>
-<span class="source-line-no">972</span><span id="line-972">    }</span>
-<span class="source-line-no">973</span><span id="line-973">    return true;</span>
-<span class="source-line-no">974</span><span id="line-974">  }</span>
-<span class="source-line-no">975</span><span id="line-975"></span>
-<span class="source-line-no">976</span><span id="line-976">  @Override</span>
-<span class="source-line-no">977</span><span id="line-977">  public long getReadPoint() {</span>
-<span class="source-line-no">978</span><span id="line-978">    return this.readPt;</span>
-<span class="source-line-no">979</span><span id="line-979">  }</span>
-<span class="source-line-no">980</span><span id="line-980"></span>
-<span class="source-line-no">981</span><span id="line-981">  private static void clearAndClose(List&lt;KeyValueScanner&gt; scanners) {</span>
-<span class="source-line-no">982</span><span id="line-982">    if (scanners == null) {</span>
-<span class="source-line-no">983</span><span id="line-983">      return;</span>
-<span class="source-line-no">984</span><span id="line-984">    }</span>
-<span class="source-line-no">985</span><span id="line-985">    for (KeyValueScanner s : scanners) {</span>
-<span class="source-line-no">986</span><span id="line-986">      s.close();</span>
-<span class="source-line-no">987</span><span id="line-987">    }</span>
-<span class="source-line-no">988</span><span id="line-988">    scanners.clear();</span>
-<span class="source-line-no">989</span><span id="line-989">  }</span>
-<span class="source-line-no">990</span><span id="line-990"></span>
-<span class="source-line-no">991</span><span id="line-991">  // Implementation of ChangedReadersObserver</span>
-<span class="source-line-no">992</span><span id="line-992">  @Override</span>
-<span class="source-line-no">993</span><span id="line-993">  public void updateReaders(List&lt;HStoreFile&gt; sfs, List&lt;KeyValueScanner&gt; memStoreScanners)</span>
-<span class="source-line-no">994</span><span id="line-994">    throws IOException {</span>
-<span class="source-line-no">995</span><span id="line-995">    if (CollectionUtils.isEmpty(sfs) &amp;&amp; CollectionUtils.isEmpty(memStoreScanners)) {</span>
-<span class="source-line-no">996</span><span id="line-996">      return;</span>
-<span class="source-line-no">997</span><span id="line-997">    }</span>
-<span class="source-line-no">998</span><span id="line-998">    boolean updateReaders = false;</span>
-<span class="source-line-no">999</span><span id="line-999">    flushLock.lock();</span>
-<span class="source-line-no">1000</span><span id="line-1000">    try {</span>
-<span class="source-line-no">1001</span><span id="line-1001">      if (!closeLock.tryLock()) {</span>
-<span class="source-line-no">1002</span><span id="line-1002">        // The reason for doing this is that when the current store scanner does not retrieve</span>
-<span class="source-line-no">1003</span><span id="line-1003">        // any new cells, then the scanner is considered to be done. The heap of this scanner</span>
-<span class="source-line-no">1004</span><span id="line-1004">        // is not closed till the shipped() call is completed. Hence in that case if at all</span>
-<span class="source-line-no">1005</span><span id="line-1005">        // the partial close (close (false)) has been called before updateReaders(), there is no</span>
-<span class="source-line-no">1006</span><span id="line-1006">        // need for the updateReaders() to happen.</span>
-<span class="source-line-no">1007</span><span id="line-1007">        LOG.debug("StoreScanner already has the close lock. There is no need to updateReaders");</span>
-<span class="source-line-no">1008</span><span id="line-1008">        // no lock acquired.</span>
-<span class="source-line-no">1009</span><span id="line-1009">        clearAndClose(memStoreScanners);</span>
-<span class="source-line-no">1010</span><span id="line-1010">        return;</span>
-<span class="source-line-no">1011</span><span id="line-1011">      }</span>
-<span class="source-line-no">1012</span><span id="line-1012">      // lock acquired</span>
-<span class="source-line-no">1013</span><span id="line-1013">      updateReaders = true;</span>
-<span class="source-line-no">1014</span><span id="line-1014">      if (this.closing) {</span>
-<span class="source-line-no">1015</span><span id="line-1015">        LOG.debug("StoreScanner already closing. There is no need to updateReaders");</span>
-<span class="source-line-no">1016</span><span id="line-1016">        clearAndClose(memStoreScanners);</span>
-<span class="source-line-no">1017</span><span id="line-1017">        return;</span>
-<span class="source-line-no">1018</span><span id="line-1018">      }</span>
-<span class="source-line-no">1019</span><span id="line-1019">      flushed = true;</span>
-<span class="source-line-no">1020</span><span id="line-1020">      final boolean isCompaction = false;</span>
-<span class="source-line-no">1021</span><span id="line-1021">      boolean usePread = get || scanUsePread;</span>
-<span class="source-line-no">1022</span><span id="line-1022">      // SEE HBASE-19468 where the flushed files are getting compacted even before a scanner</span>
-<span class="source-line-no">1023</span><span id="line-1023">      // calls next(). So its better we create scanners here rather than next() call. Ensure</span>
-<span class="source-line-no">1024</span><span id="line-1024">      // these scanners are properly closed() whether or not the scan is completed successfully</span>
-<span class="source-line-no">1025</span><span id="line-1025">      // Eagerly creating scanners so that we have the ref counting ticking on the newly created</span>
-<span class="source-line-no">1026</span><span id="line-1026">      // store files. In case of stream scanners this eager creation does not induce performance</span>
-<span class="source-line-no">1027</span><span id="line-1027">      // penalty because in scans (that uses stream scanners) the next() call is bound to happen.</span>
-<span class="source-line-no">1028</span><span id="line-1028">      List&lt;KeyValueScanner&gt; scanners =</span>
-<span class="source-line-no">1029</span><span id="line-1029">        store.getScanners(sfs, cacheBlocks, get, usePread, isCompaction, matcher,</span>
-<span class="source-line-no">1030</span><span id="line-1030">          scan.getStartRow(), scan.getStopRow(), this.readPt, false, isOnlyLatestVersionScan(scan));</span>
-<span class="source-line-no">1031</span><span id="line-1031">      flushedstoreFileScanners.addAll(scanners);</span>
-<span class="source-line-no">1032</span><span id="line-1032">      if (!CollectionUtils.isEmpty(memStoreScanners)) {</span>
-<span class="source-line-no">1033</span><span id="line-1033">        clearAndClose(memStoreScannersAfterFlush);</span>
-<span class="source-line-no">1034</span><span id="line-1034">        memStoreScannersAfterFlush.addAll(memStoreScanners);</span>
-<span class="source-line-no">1035</span><span id="line-1035">      }</span>
-<span class="source-line-no">1036</span><span id="line-1036">    } finally {</span>
-<span class="source-line-no">1037</span><span id="line-1037">      flushLock.unlock();</span>
-<span class="source-line-no">1038</span><span id="line-1038">      if (updateReaders) {</span>
-<span class="source-line-no">1039</span><span id="line-1039">        closeLock.unlock();</span>
-<span class="source-line-no">1040</span><span id="line-1040">      }</span>
-<span class="source-line-no">1041</span><span id="line-1041">      if (hasUpdatedReaders != null) {</span>
-<span class="source-line-no">1042</span><span id="line-1042">        hasUpdatedReaders.set(true);</span>
-<span class="source-line-no">1043</span><span id="line-1043">      }</span>
-<span class="source-line-no">1044</span><span id="line-1044">    }</span>
-<span class="source-line-no">1045</span><span id="line-1045">    // Let the next() call handle re-creating and seeking</span>
-<span class="source-line-no">1046</span><span id="line-1046">  }</span>
-<span class="source-line-no">1047</span><span id="line-1047"></span>
-<span class="source-line-no">1048</span><span id="line-1048">  /** Returns if top of heap has changed (and KeyValueHeap has to try the next KV) */</span>
-<span class="source-line-no">1049</span><span id="line-1049">  protected final boolean reopenAfterFlush() throws IOException {</span>
-<span class="source-line-no">1050</span><span id="line-1050">    // here we can make sure that we have a Store instance so no null check on store.</span>
-<span class="source-line-no">1051</span><span id="line-1051">    ExtendedCell lastTop = heap.peek();</span>
-<span class="source-line-no">1052</span><span id="line-1052">    // When we have the scan object, should we not pass it to getScanners() to get a limited set of</span>
-<span class="source-line-no">1053</span><span id="line-1053">    // scanners? We did so in the constructor and we could have done it now by storing the scan</span>
-<span class="source-line-no">1054</span><span id="line-1054">    // object from the constructor</span>
-<span class="source-line-no">1055</span><span id="line-1055">    List&lt;KeyValueScanner&gt; scanners;</span>
-<span class="source-line-no">1056</span><span id="line-1056">    flushLock.lock();</span>
-<span class="source-line-no">1057</span><span id="line-1057">    try {</span>
-<span class="source-line-no">1058</span><span id="line-1058">      List&lt;KeyValueScanner&gt; allScanners =</span>
-<span class="source-line-no">1059</span><span id="line-1059">        new ArrayList&lt;&gt;(flushedstoreFileScanners.size() + memStoreScannersAfterFlush.size());</span>
-<span class="source-line-no">1060</span><span id="line-1060">      allScanners.addAll(flushedstoreFileScanners);</span>
-<span class="source-line-no">1061</span><span id="line-1061">      allScanners.addAll(memStoreScannersAfterFlush);</span>
-<span class="source-line-no">1062</span><span id="line-1062">      scanners = selectScannersFrom(store, allScanners);</span>
-<span class="source-line-no">1063</span><span id="line-1063">      // Clear the current set of flushed store files scanners so that they don't get added again</span>
-<span class="source-line-no">1064</span><span id="line-1064">      flushedstoreFileScanners.clear();</span>
-<span class="source-line-no">1065</span><span id="line-1065">      memStoreScannersAfterFlush.clear();</span>
-<span class="source-line-no">1066</span><span id="line-1066">    } finally {</span>
-<span class="source-line-no">1067</span><span id="line-1067">      flushLock.unlock();</span>
-<span class="source-line-no">1068</span><span id="line-1068">    }</span>
-<span class="source-line-no">1069</span><span id="line-1069"></span>
-<span class="source-line-no">1070</span><span id="line-1070">    // Seek the new scanners to the last key</span>
-<span class="source-line-no">1071</span><span id="line-1071">    seekScanners(scanners, lastTop, false, parallelSeekEnabled);</span>
-<span class="source-line-no">1072</span><span id="line-1072">    // remove the older memstore scanner</span>
-<span class="source-line-no">1073</span><span id="line-1073">    for (int i = currentScanners.size() - 1; i &gt;= 0; i--) {</span>
-<span class="source-line-no">1074</span><span id="line-1074">      if (!currentScanners.get(i).isFileScanner()) {</span>
-<span class="source-line-no">1075</span><span id="line-1075">        scannersForDelayedClose.add(currentScanners.remove(i));</span>
-<span class="source-line-no">1076</span><span id="line-1076">      } else {</span>
-<span class="source-line-no">1077</span><span id="line-1077">        // we add the memstore scanner to the end of currentScanners</span>
-<span class="source-line-no">1078</span><span id="line-1078">        break;</span>
-<span class="source-line-no">1079</span><span id="line-1079">      }</span>
-<span class="source-line-no">1080</span><span id="line-1080">    }</span>
-<span class="source-line-no">1081</span><span id="line-1081">    // add the newly created scanners on the flushed files and the current active memstore scanner</span>
-<span class="source-line-no">1082</span><span id="line-1082">    addCurrentScanners(scanners);</span>
-<span class="source-line-no">1083</span><span id="line-1083">    // Combine all seeked scanners with a heap</span>
-<span class="source-line-no">1084</span><span id="line-1084">    resetKVHeap(this.currentScanners, store.getComparator());</span>
-<span class="source-line-no">1085</span><span id="line-1085">    resetQueryMatcher(lastTop);</span>
-<span class="source-line-no">1086</span><span id="line-1086">    if (heap.peek() == null || store.getComparator().compareRows(lastTop, this.heap.peek()) != 0) {</span>
-<span class="source-line-no">1087</span><span id="line-1087">      LOG.info("Storescanner.peek() is changed where before = " + lastTop.toString()</span>
-<span class="source-line-no">1088</span><span id="line-1088">        + ",and after = " + heap.peek());</span>
-<span class="source-line-no">1089</span><span id="line-1089">      topChanged = true;</span>
-<span class="source-line-no">1090</span><span id="line-1090">    } else {</span>
-<span class="source-line-no">1091</span><span id="line-1091">      topChanged = false;</span>
-<span class="source-line-no">1092</span><span id="line-1092">    }</span>
-<span class="source-line-no">1093</span><span id="line-1093">    return topChanged;</span>
-<span class="source-line-no">1094</span><span id="line-1094">  }</span>
-<span class="source-line-no">1095</span><span id="line-1095"></span>
-<span class="source-line-no">1096</span><span id="line-1096">  private void resetQueryMatcher(ExtendedCell lastTopKey) {</span>
-<span class="source-line-no">1097</span><span id="line-1097">    // Reset the state of the Query Matcher and set to top row.</span>
-<span class="source-line-no">1098</span><span id="line-1098">    // Only reset and call setRow if the row changes; avoids confusing the</span>
-<span class="source-line-no">1099</span><span id="line-1099">    // query matcher if scanning intra-row.</span>
-<span class="source-line-no">1100</span><span id="line-1100">    ExtendedCell cell = heap.peek();</span>
-<span class="source-line-no">1101</span><span id="line-1101">    if (cell == null) {</span>
-<span class="source-line-no">1102</span><span id="line-1102">      cell = lastTopKey;</span>
-<span class="source-line-no">1103</span><span id="line-1103">    }</span>
-<span class="source-line-no">1104</span><span id="line-1104">    if ((matcher.currentRow() == null) || !CellUtil.matchingRows(cell, matcher.currentRow())) {</span>
-<span class="source-line-no">1105</span><span id="line-1105">      this.countPerRow = 0;</span>
-<span class="source-line-no">1106</span><span id="line-1106">      // The setToNewRow will call reset internally</span>
-<span class="source-line-no">1107</span><span id="line-1107">      matcher.setToNewRow(cell);</span>
-<span class="source-line-no">1108</span><span id="line-1108">    }</span>
-<span class="source-line-no">1109</span><span id="line-1109">  }</span>
-<span class="source-line-no">1110</span><span id="line-1110"></span>
-<span class="source-line-no">1111</span><span id="line-1111">  /**</span>
-<span class="source-line-no">1112</span><span id="line-1112">   * Check whether scan as expected order</span>
-<span class="source-line-no">1113</span><span id="line-1113">   */</span>
-<span class="source-line-no">1114</span><span id="line-1114">  protected void checkScanOrder(Cell prevKV, Cell kv, CellComparator comparator)</span>
-<span class="source-line-no">1115</span><span id="line-1115">    throws IOException {</span>
-<span class="source-line-no">1116</span><span id="line-1116">    // Check that the heap gives us KVs in an increasing order.</span>
-<span class="source-line-no">1117</span><span id="line-1117">    assert prevKV == null || comparator == null || comparator.compare(prevKV, kv) &lt;= 0</span>
-<span class="source-line-no">1118</span><span id="line-1118">      : "Key " + prevKV + " followed by a smaller key " + kv + " in cf " + store;</span>
-<span class="source-line-no">1119</span><span id="line-1119">  }</span>
-<span class="source-line-no">1120</span><span id="line-1120"></span>
-<span class="source-line-no">1121</span><span id="line-1121">  protected boolean seekToNextRow(ExtendedCell c) throws IOException {</span>
-<span class="source-line-no">1122</span><span id="line-1122">    return reseek(PrivateCellUtil.createLastOnRow(c));</span>
-<span class="source-line-no">1123</span><span id="line-1123">  }</span>
-<span class="source-line-no">1124</span><span id="line-1124"></span>
-<span class="source-line-no">1125</span><span id="line-1125">  /**</span>
-<span class="source-line-no">1126</span><span id="line-1126">   * Do a reseek in a normal StoreScanner(scan forward)</span>
-<span class="source-line-no">1127</span><span id="line-1127">   * @return true if scanner has values left, false if end of scanner</span>
-<span class="source-line-no">1128</span><span id="line-1128">   */</span>
-<span class="source-line-no">1129</span><span id="line-1129">  protected boolean seekAsDirection(ExtendedCell kv) throws IOException {</span>
-<span class="source-line-no">1130</span><span id="line-1130">    return reseek(kv);</span>
-<span class="source-line-no">1131</span><span id="line-1131">  }</span>
-<span class="source-line-no">1132</span><span id="line-1132"></span>
-<span class="source-line-no">1133</span><span id="line-1133">  @Override</span>
-<span class="source-line-no">1134</span><span id="line-1134">  public boolean reseek(ExtendedCell kv) throws IOException {</span>
-<span class="source-line-no">1135</span><span id="line-1135">    if (checkFlushed()) {</span>
-<span class="source-line-no">1136</span><span id="line-1136">      reopenAfterFlush();</span>
-<span class="source-line-no">1137</span><span id="line-1137">    }</span>
-<span class="source-line-no">1138</span><span id="line-1138">    if (explicitColumnQuery &amp;&amp; lazySeekEnabledGlobally) {</span>
-<span class="source-line-no">1139</span><span id="line-1139">      return heap.requestSeek(kv, true, useRowColBloom);</span>
-<span class="source-line-no">1140</span><span id="line-1140">    }</span>
-<span class="source-line-no">1141</span><span id="line-1141">    return heap.reseek(kv);</span>
-<span class="source-line-no">1142</span><span id="line-1142">  }</span>
-<span class="source-line-no">1143</span><span id="line-1143"></span>
-<span class="source-line-no">1144</span><span id="line-1144">  void trySwitchToStreamRead() {</span>
-<span class="source-line-no">1145</span><span id="line-1145">    if (</span>
-<span class="source-line-no">1146</span><span id="line-1146">      readType != Scan.ReadType.DEFAULT || !scanUsePread || closing || heap.peek() == null</span>
-<span class="source-line-no">1147</span><span id="line-1147">        || bytesRead &lt; preadMaxBytes</span>
-<span class="source-line-no">1148</span><span id="line-1148">    ) {</span>
-<span class="source-line-no">1149</span><span id="line-1149">      return;</span>
-<span class="source-line-no">1150</span><span id="line-1150">    }</span>
-<span class="source-line-no">1151</span><span id="line-1151">    LOG.debug("Switch to stream read (scanned={} bytes) of {}", bytesRead,</span>
-<span class="source-line-no">1152</span><span id="line-1152">      this.store.getColumnFamilyName());</span>
-<span class="source-line-no">1153</span><span id="line-1153">    scanUsePread = false;</span>
-<span class="source-line-no">1154</span><span id="line-1154">    ExtendedCell lastTop = heap.peek();</span>
-<span class="source-line-no">1155</span><span id="line-1155">    List&lt;KeyValueScanner&gt; memstoreScanners = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">1156</span><span id="line-1156">    List&lt;KeyValueScanner&gt; scannersToClose = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">1157</span><span id="line-1157">    for (KeyValueScanner kvs : currentScanners) {</span>
-<span class="source-line-no">1158</span><span id="line-1158">      if (!kvs.isFileScanner()) {</span>
-<span class="source-line-no">1159</span><span id="line-1159">        // collect memstorescanners here</span>
-<span class="source-line-no">1160</span><span id="line-1160">        memstoreScanners.add(kvs);</span>
-<span class="source-line-no">1161</span><span id="line-1161">      } else {</span>
-<span class="source-line-no">1162</span><span id="line-1162">        scannersToClose.add(kvs);</span>
-<span class="source-line-no">1163</span><span id="line-1163">      }</span>
-<span class="source-line-no">1164</span><span id="line-1164">    }</span>
-<span class="source-line-no">1165</span><span id="line-1165">    List&lt;KeyValueScanner&gt; fileScanners = null;</span>
-<span class="source-line-no">1166</span><span id="line-1166">    List&lt;KeyValueScanner&gt; newCurrentScanners;</span>
-<span class="source-line-no">1167</span><span id="line-1167">    KeyValueHeap newHeap;</span>
-<span class="source-line-no">1168</span><span id="line-1168">    try {</span>
-<span class="source-line-no">1169</span><span id="line-1169">      // We must have a store instance here so no null check</span>
-<span class="source-line-no">1170</span><span id="line-1170">      // recreate the scanners on the current file scanners</span>
-<span class="source-line-no">1171</span><span id="line-1171">      fileScanners = store.recreateScanners(scannersToClose, cacheBlocks, false, false, matcher,</span>
-<span class="source-line-no">1172</span><span id="line-1172">        scan.getStartRow(), scan.includeStartRow(), scan.getStopRow(), scan.includeStopRow(),</span>
-<span class="source-line-no">1173</span><span id="line-1173">        readPt, false);</span>
-<span class="source-line-no">1174</span><span id="line-1174">      if (fileScanners == null) {</span>
-<span class="source-line-no">1175</span><span id="line-1175">        return;</span>
-<span class="source-line-no">1176</span><span id="line-1176">      }</span>
-<span class="source-line-no">1177</span><span id="line-1177">      seekScanners(fileScanners, lastTop, false, parallelSeekEnabled);</span>
-<span class="source-line-no">1178</span><span id="line-1178">      newCurrentScanners = new ArrayList&lt;&gt;(fileScanners.size() + memstoreScanners.size());</span>
-<span class="source-line-no">1179</span><span id="line-1179">      newCurrentScanners.addAll(fileScanners);</span>
-<span class="source-line-no">1180</span><span id="line-1180">      newCurrentScanners.addAll(memstoreScanners);</span>
-<span class="source-line-no">1181</span><span id="line-1181">      newHeap = newKVHeap(newCurrentScanners, comparator);</span>
-<span class="source-line-no">1182</span><span id="line-1182">    } catch (Exception e) {</span>
-<span class="source-line-no">1183</span><span id="line-1183">      LOG.warn("failed to switch to stream read", e);</span>
-<span class="source-line-no">1184</span><span id="line-1184">      if (fileScanners != null) {</span>
-<span class="source-line-no">1185</span><span id="line-1185">        fileScanners.forEach(KeyValueScanner::close);</span>
-<span class="source-line-no">1186</span><span id="line-1186">      }</span>
-<span class="source-line-no">1187</span><span id="line-1187">      return;</span>
-<span class="source-line-no">1188</span><span id="line-1188">    }</span>
-<span class="source-line-no">1189</span><span id="line-1189">    currentScanners.clear();</span>
-<span class="source-line-no">1190</span><span id="line-1190">    addCurrentScanners(newCurrentScanners);</span>
-<span class="source-line-no">1191</span><span id="line-1191">    this.heap = newHeap;</span>
-<span class="source-line-no">1192</span><span id="line-1192">    resetQueryMatcher(lastTop);</span>
-<span class="source-line-no">1193</span><span id="line-1193">    scannersToClose.forEach(KeyValueScanner::close);</span>
-<span class="source-line-no">1194</span><span id="line-1194">    if (hasSwitchedToStreamRead != null) {</span>
-<span class="source-line-no">1195</span><span id="line-1195">      hasSwitchedToStreamRead.set(true);</span>
-<span class="source-line-no">1196</span><span id="line-1196">    }</span>
-<span class="source-line-no">1197</span><span id="line-1197">  }</span>
-<span class="source-line-no">1198</span><span id="line-1198"></span>
-<span class="source-line-no">1199</span><span id="line-1199">  protected final boolean checkFlushed() {</span>
-<span class="source-line-no">1200</span><span id="line-1200">    // check the var without any lock. Suppose even if we see the old</span>
-<span class="source-line-no">1201</span><span id="line-1201">    // value here still it is ok to continue because we will not be resetting</span>
-<span class="source-line-no">1202</span><span id="line-1202">    // the heap but will continue with the referenced memstore's snapshot. For compactions</span>
-<span class="source-line-no">1203</span><span id="line-1203">    // any way we don't need the updateReaders at all to happen as we still continue with</span>
-<span class="source-line-no">1204</span><span id="line-1204">    // the older files</span>
-<span class="source-line-no">1205</span><span id="line-1205">    if (flushed) {</span>
-<span class="source-line-no">1206</span><span id="line-1206">      // If there is a flush and the current scan is notified on the flush ensure that the</span>
-<span class="source-line-no">1207</span><span id="line-1207">      // scan's heap gets reset and we do a seek on the newly flushed file.</span>
-<span class="source-line-no">1208</span><span id="line-1208">      if (this.closing) {</span>
-<span class="source-line-no">1209</span><span id="line-1209">        return false;</span>
-<span class="source-line-no">1210</span><span id="line-1210">      }</span>
-<span class="source-line-no">1211</span><span id="line-1211">      // reset the flag</span>
-<span class="source-line-no">1212</span><span id="line-1212">      flushed = false;</span>
-<span class="source-line-no">1213</span><span id="line-1213">      return true;</span>
-<span class="source-line-no">1214</span><span id="line-1214">    }</span>
-<span class="source-line-no">1215</span><span id="line-1215">    return false;</span>
-<span class="source-line-no">1216</span><span id="line-1216">  }</span>
-<span class="source-line-no">1217</span><span id="line-1217"></span>
-<span class="source-line-no">1218</span><span id="line-1218">  /**</span>
-<span class="source-line-no">1219</span><span id="line-1219">   * Seek storefiles in parallel to optimize IO latency as much as possible</span>
-<span class="source-line-no">1220</span><span id="line-1220">   * @param scanners the list {@link KeyValueScanner}s to be read from</span>
-<span class="source-line-no">1221</span><span id="line-1221">   * @param kv       the KeyValue on which the operation is being requested</span>
-<span class="source-line-no">1222</span><span id="line-1222">   */</span>
-<span class="source-line-no">1223</span><span id="line-1223">  private void parallelSeek(final List&lt;? extends KeyValueScanner&gt; scanners, final ExtendedCell kv)</span>
-<span class="source-line-no">1224</span><span id="line-1224">    throws IOException {</span>
-<span class="source-line-no">1225</span><span id="line-1225">    if (scanners.isEmpty()) return;</span>
-<span class="source-line-no">1226</span><span id="line-1226">    int storeFileScannerCount = scanners.size();</span>
-<span class="source-line-no">1227</span><span id="line-1227">    CountDownLatch latch = new CountDownLatch(storeFileScannerCount);</span>
-<span class="source-line-no">1228</span><span id="line-1228">    List&lt;ParallelSeekHandler&gt; handlers = new ArrayList&lt;&gt;(storeFileScannerCount);</span>
-<span class="source-line-no">1229</span><span id="line-1229">    for (KeyValueScanner scanner : scanners) {</span>
-<span class="source-line-no">1230</span><span id="line-1230">      if (scanner instanceof StoreFileScanner) {</span>
-<span class="source-line-no">1231</span><span id="line-1231">        ParallelSeekHandler seekHandler = new ParallelSeekHandler(scanner, kv, this.readPt, latch);</span>
-<span class="source-line-no">1232</span><span id="line-1232">        executor.submit(seekHandler);</span>
-<span class="source-line-no">1233</span><span id="line-1233">        handlers.add(seekHandler);</span>
-<span class="source-line-no">1234</span><span id="line-1234">      } else {</span>
-<span class="source-line-no">1235</span><span id="line-1235">        scanner.seek(kv);</span>
-<span class="source-line-no">1236</span><span id="line-1236">        latch.countDown();</span>
-<span class="source-line-no">1237</span><span id="line-1237">      }</span>
-<span class="source-line-no">1238</span><span id="line-1238">    }</span>
-<span class="source-line-no">1239</span><span id="line-1239"></span>
-<span class="source-line-no">1240</span><span id="line-1240">    try {</span>
-<span class="source-line-no">1241</span><span id="line-1241">      latch.await();</span>
-<span class="source-line-no">1242</span><span id="line-1242">    } catch (InterruptedException ie) {</span>
-<span class="source-line-no">1243</span><span id="line-1243">      throw (InterruptedIOException) new InterruptedIOException().initCause(ie);</span>
-<span class="source-line-no">1244</span><span id="line-1244">    }</span>
-<span class="source-line-no">1245</span><span id="line-1245"></span>
-<span class="source-line-no">1246</span><span id="line-1246">    for (ParallelSeekHandler handler : handlers) {</span>
-<span class="source-line-no">1247</span><span id="line-1247">      if (handler.getErr() != null) {</span>
-<span class="source-line-no">1248</span><span id="line-1248">        throw new IOException(handler.getErr());</span>
-<span class="source-line-no">1249</span><span id="line-1249">      }</span>
-<span class="source-line-no">1250</span><span id="line-1250">    }</span>
-<span class="source-line-no">1251</span><span id="line-1251">  }</span>
-<span class="source-line-no">1252</span><span id="line-1252"></span>
-<span class="source-line-no">1253</span><span id="line-1253">  /**</span>
-<span class="source-line-no">1254</span><span id="line-1254">   * Used in testing.</span>
-<span class="source-line-no">1255</span><span id="line-1255">   * @return all scanners in no particular order</span>
-<span class="source-line-no">1256</span><span id="line-1256">   */</span>
-<span class="source-line-no">1257</span><span id="line-1257">  List&lt;KeyValueScanner&gt; getAllScannersForTesting() {</span>
-<span class="source-line-no">1258</span><span id="line-1258">    List&lt;KeyValueScanner&gt; allScanners = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">1259</span><span id="line-1259">    KeyValueScanner current = heap.getCurrentForTesting();</span>
-<span class="source-line-no">1260</span><span id="line-1260">    if (current != null) allScanners.add(current);</span>
-<span class="source-line-no">1261</span><span id="line-1261">    for (KeyValueScanner scanner : heap.getHeap())</span>
-<span class="source-line-no">1262</span><span id="line-1262">      allScanners.add(scanner);</span>
-<span class="source-line-no">1263</span><span id="line-1263">    return allScanners;</span>
-<span class="source-line-no">1264</span><span id="line-1264">  }</span>
-<span class="source-line-no">1265</span><span id="line-1265"></span>
-<span class="source-line-no">1266</span><span id="line-1266">  static void enableLazySeekGlobally(boolean enable) {</span>
-<span class="source-line-no">1267</span><span id="line-1267">    lazySeekEnabledGlobally = enable;</span>
-<span class="source-line-no">1268</span><span id="line-1268">  }</span>
-<span class="source-line-no">1269</span><span id="line-1269"></span>
-<span class="source-line-no">1270</span><span id="line-1270">  /** Returns The estimated number of KVs seen by this scanner (includes some skipped KVs). */</span>
-<span class="source-line-no">1271</span><span id="line-1271">  public long getEstimatedNumberOfKvsScanned() {</span>
-<span class="source-line-no">1272</span><span id="line-1272">    return this.kvsScanned;</span>
-<span class="source-line-no">1273</span><span id="line-1273">  }</span>
-<span class="source-line-no">1274</span><span id="line-1274"></span>
-<span class="source-line-no">1275</span><span id="line-1275">  @Override</span>
-<span class="source-line-no">1276</span><span id="line-1276">  public ExtendedCell getNextIndexedKey() {</span>
-<span class="source-line-no">1277</span><span id="line-1277">    return this.heap.getNextIndexedKey();</span>
-<span class="source-line-no">1278</span><span id="line-1278">  }</span>
-<span class="source-line-no">1279</span><span id="line-1279"></span>
-<span class="source-line-no">1280</span><span id="line-1280">  @Override</span>
-<span class="source-line-no">1281</span><span id="line-1281">  public void shipped() throws IOException {</span>
-<span class="source-line-no">1282</span><span id="line-1282">    if (prevCell != null) {</span>
-<span class="source-line-no">1283</span><span id="line-1283">      // Do the copy here so that in case the prevCell ref is pointing to the previous</span>
-<span class="source-line-no">1284</span><span id="line-1284">      // blocks we can safely release those blocks.</span>
-<span class="source-line-no">1285</span><span id="line-1285">      // This applies to blocks that are got from Bucket cache, L1 cache and the blocks</span>
-<span class="source-line-no">1286</span><span id="line-1286">      // fetched from HDFS. Copying this would ensure that we let go the references to these</span>
-<span class="source-line-no">1287</span><span id="line-1287">      // blocks so that they can be GCed safely(in case of bucket cache)</span>
-<span class="source-line-no">1288</span><span id="line-1288">      prevCell = KeyValueUtil.toNewKeyCell(this.prevCell);</span>
-<span class="source-line-no">1289</span><span id="line-1289">    }</span>
-<span class="source-line-no">1290</span><span id="line-1290">    matcher.beforeShipped();</span>
-<span class="source-line-no">1291</span><span id="line-1291">    // There wont be further fetch of Cells from these scanners. Just close.</span>
-<span class="source-line-no">1292</span><span id="line-1292">    clearAndClose(scannersForDelayedClose);</span>
-<span class="source-line-no">1293</span><span id="line-1293">    if (this.heap != null) {</span>
-<span class="source-line-no">1294</span><span id="line-1294">      this.heap.shipped();</span>
-<span class="source-line-no">1295</span><span id="line-1295">      // When switching from pread to stream, we will open a new scanner for each store file, but</span>
-<span class="source-line-no">1296</span><span id="line-1296">      // the old scanner may still track the HFileBlocks we have scanned but not sent back to client</span>
-<span class="source-line-no">1297</span><span id="line-1297">      // yet. If we close the scanner immediately then the HFileBlocks may be messed up by others</span>
-<span class="source-line-no">1298</span><span id="line-1298">      // before we serialize and send it back to client. The HFileBlocks will be released in shipped</span>
-<span class="source-line-no">1299</span><span id="line-1299">      // method, so we here will also open new scanners and close old scanners in shipped method.</span>
-<span class="source-line-no">1300</span><span id="line-1300">      // See HBASE-18055 for more details.</span>
-<span class="source-line-no">1301</span><span id="line-1301">      trySwitchToStreamRead();</span>
-<span class="source-line-no">1302</span><span id="line-1302">    }</span>
-<span class="source-line-no">1303</span><span id="line-1303">  }</span>
-<span class="source-line-no">1304</span><span id="line-1304"></span>
-<span class="source-line-no">1305</span><span id="line-1305">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
-<span class="source-line-no">1306</span><span id="line-1306">  static final void instrument() {</span>
-<span class="source-line-no">1307</span><span id="line-1307">    hasUpdatedReaders = new AtomicBoolean(false);</span>
-<span class="source-line-no">1308</span><span id="line-1308">    hasSwitchedToStreamRead = new AtomicBoolean(false);</span>
-<span class="source-line-no">1309</span><span id="line-1309">  }</span>
-<span class="source-line-no">1310</span><span id="line-1310"></span>
-<span class="source-line-no">1311</span><span id="line-1311">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
-<span class="source-line-no">1312</span><span id="line-1312">  static final boolean hasUpdatedReaders() {</span>
-<span class="source-line-no">1313</span><span id="line-1313">    return hasUpdatedReaders.get();</span>
-<span class="source-line-no">1314</span><span id="line-1314">  }</span>
-<span class="source-line-no">1315</span><span id="line-1315"></span>
-<span class="source-line-no">1316</span><span id="line-1316">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
-<span class="source-line-no">1317</span><span id="line-1317">  static final boolean hasSwitchedToStreamRead() {</span>
-<span class="source-line-no">1318</span><span id="line-1318">    return hasSwitchedToStreamRead.get();</span>
-<span class="source-line-no">1319</span><span id="line-1319">  }</span>
-<span class="source-line-no">1320</span><span id="line-1320"></span>
-<span class="source-line-no">1321</span><span id="line-1321">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
-<span class="source-line-no">1322</span><span id="line-1322">  static final void resetHasUpdatedReaders() {</span>
-<span class="source-line-no">1323</span><span id="line-1323">    hasUpdatedReaders.set(false);</span>
-<span class="source-line-no">1324</span><span id="line-1324">  }</span>
-<span class="source-line-no">1325</span><span id="line-1325"></span>
-<span class="source-line-no">1326</span><span id="line-1326">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
-<span class="source-line-no">1327</span><span id="line-1327">  static final void resetHasSwitchedToStreamRead() {</span>
-<span class="source-line-no">1328</span><span id="line-1328">    hasSwitchedToStreamRead.set(false);</span>
-<span class="source-line-no">1329</span><span id="line-1329">  }</span>
-<span class="source-line-no">1330</span><span id="line-1330">}</span>
+<span class="source-line-no">967</span><span id="line-967">    // ROWCOL bloom filter optimization. See HBASE-19863 and HBASE-29907 for more details</span>
+<span class="source-line-no">968</span><span id="line-968">    if (useRowColBloom &amp;&amp; nextCell != null &amp;&amp; matcher.compareKeyForNextColumn(nextCell, cell) &lt; 0) {</span>
+<span class="source-line-no">969</span><span id="line-969">      return false;</span>
+<span class="source-line-no">970</span><span id="line-970">    }</span>
+<span class="source-line-no">971</span><span id="line-971">    return true;</span>
+<span class="source-line-no">972</span><span id="line-972">  }</span>
+<span class="source-line-no">973</span><span id="line-973"></span>
+<span class="source-line-no">974</span><span id="line-974">  @Override</span>
+<span class="source-line-no">975</span><span id="line-975">  public long getReadPoint() {</span>
+<span class="source-line-no">976</span><span id="line-976">    return this.readPt;</span>
+<span class="source-line-no">977</span><span id="line-977">  }</span>
+<span class="source-line-no">978</span><span id="line-978"></span>
+<span class="source-line-no">979</span><span id="line-979">  private static void clearAndClose(List&lt;KeyValueScanner&gt; scanners) {</span>
+<span class="source-line-no">980</span><span id="line-980">    if (scanners == null) {</span>
+<span class="source-line-no">981</span><span id="line-981">      return;</span>
+<span class="source-line-no">982</span><span id="line-982">    }</span>
+<span class="source-line-no">983</span><span id="line-983">    for (KeyValueScanner s : scanners) {</span>
+<span class="source-line-no">984</span><span id="line-984">      s.close();</span>
+<span class="source-line-no">985</span><span id="line-985">    }</span>
+<span class="source-line-no">986</span><span id="line-986">    scanners.clear();</span>
+<span class="source-line-no">987</span><span id="line-987">  }</span>
+<span class="source-line-no">988</span><span id="line-988"></span>
+<span class="source-line-no">989</span><span id="line-989">  // Implementation of ChangedReadersObserver</span>
+<span class="source-line-no">990</span><span id="line-990">  @Override</span>
+<span class="source-line-no">991</span><span id="line-991">  public void updateReaders(List&lt;HStoreFile&gt; sfs, List&lt;KeyValueScanner&gt; memStoreScanners)</span>
+<span class="source-line-no">992</span><span id="line-992">    throws IOException {</span>
+<span class="source-line-no">993</span><span id="line-993">    if (CollectionUtils.isEmpty(sfs) &amp;&amp; CollectionUtils.isEmpty(memStoreScanners)) {</span>
+<span class="source-line-no">994</span><span id="line-994">      return;</span>
+<span class="source-line-no">995</span><span id="line-995">    }</span>
+<span class="source-line-no">996</span><span id="line-996">    boolean updateReaders = false;</span>
+<span class="source-line-no">997</span><span id="line-997">    flushLock.lock();</span>
+<span class="source-line-no">998</span><span id="line-998">    try {</span>
+<span class="source-line-no">999</span><span id="line-999">      if (!closeLock.tryLock()) {</span>
+<span class="source-line-no">1000</span><span id="line-1000">        // The reason for doing this is that when the current store scanner does not retrieve</span>
+<span class="source-line-no">1001</span><span id="line-1001">        // any new cells, then the scanner is considered to be done. The heap of this scanner</span>
+<span class="source-line-no">1002</span><span id="line-1002">        // is not closed till the shipped() call is completed. Hence in that case if at all</span>
+<span class="source-line-no">1003</span><span id="line-1003">        // the partial close (close (false)) has been called before updateReaders(), there is no</span>
+<span class="source-line-no">1004</span><span id="line-1004">        // need for the updateReaders() to happen.</span>
+<span class="source-line-no">1005</span><span id="line-1005">        LOG.debug("StoreScanner already has the close lock. There is no need to updateReaders");</span>
+<span class="source-line-no">1006</span><span id="line-1006">        // no lock acquired.</span>
+<span class="source-line-no">1007</span><span id="line-1007">        clearAndClose(memStoreScanners);</span>
+<span class="source-line-no">1008</span><span id="line-1008">        return;</span>
+<span class="source-line-no">1009</span><span id="line-1009">      }</span>
+<span class="source-line-no">1010</span><span id="line-1010">      // lock acquired</span>
+<span class="source-line-no">1011</span><span id="line-1011">      updateReaders = true;</span>
+<span class="source-line-no">1012</span><span id="line-1012">      if (this.closing) {</span>
+<span class="source-line-no">1013</span><span id="line-1013">        LOG.debug("StoreScanner already closing. There is no need to updateReaders");</span>
+<span class="source-line-no">1014</span><span id="line-1014">        clearAndClose(memStoreScanners);</span>
+<span class="source-line-no">1015</span><span id="line-1015">        return;</span>
+<span class="source-line-no">1016</span><span id="line-1016">      }</span>
+<span class="source-line-no">1017</span><span id="line-1017">      flushed = true;</span>
+<span class="source-line-no">1018</span><span id="line-1018">      final boolean isCompaction = false;</span>
+<span class="source-line-no">1019</span><span id="line-1019">      boolean usePread = get || scanUsePread;</span>
+<span class="source-line-no">1020</span><span id="line-1020">      // SEE HBASE-19468 where the flushed files are getting compacted even before a scanner</span>
+<span class="source-line-no">1021</span><span id="line-1021">      // calls next(). So its better we create scanners here rather than next() call. Ensure</span>
+<span class="source-line-no">1022</span><span id="line-1022">      // these scanners are properly closed() whether or not the scan is completed successfully</span>
+<span class="source-line-no">1023</span><span id="line-1023">      // Eagerly creating scanners so that we have the ref counting ticking on the newly created</span>
+<span class="source-line-no">1024</span><span id="line-1024">      // store files. In case of stream scanners this eager creation does not induce performance</span>
+<span class="source-line-no">1025</span><span id="line-1025">      // penalty because in scans (that uses stream scanners) the next() call is bound to happen.</span>
+<span class="source-line-no">1026</span><span id="line-1026">      List&lt;KeyValueScanner&gt; scanners =</span>
+<span class="source-line-no">1027</span><span id="line-1027">        store.getScanners(sfs, cacheBlocks, get, usePread, isCompaction, matcher,</span>
+<span class="source-line-no">1028</span><span id="line-1028">          scan.getStartRow(), scan.getStopRow(), this.readPt, false, isOnlyLatestVersionScan(scan));</span>
+<span class="source-line-no">1029</span><span id="line-1029">      flushedstoreFileScanners.addAll(scanners);</span>
+<span class="source-line-no">1030</span><span id="line-1030">      if (!CollectionUtils.isEmpty(memStoreScanners)) {</span>
+<span class="source-line-no">1031</span><span id="line-1031">        clearAndClose(memStoreScannersAfterFlush);</span>
+<span class="source-line-no">1032</span><span id="line-1032">        memStoreScannersAfterFlush.addAll(memStoreScanners);</span>
+<span class="source-line-no">1033</span><span id="line-1033">      }</span>
+<span class="source-line-no">1034</span><span id="line-1034">    } finally {</span>
+<span class="source-line-no">1035</span><span id="line-1035">      flushLock.unlock();</span>
+<span class="source-line-no">1036</span><span id="line-1036">      if (updateReaders) {</span>
+<span class="source-line-no">1037</span><span id="line-1037">        closeLock.unlock();</span>
+<span class="source-line-no">1038</span><span id="line-1038">      }</span>
+<span class="source-line-no">1039</span><span id="line-1039">      if (hasUpdatedReaders != null) {</span>
+<span class="source-line-no">1040</span><span id="line-1040">        hasUpdatedReaders.set(true);</span>
+<span class="source-line-no">1041</span><span id="line-1041">      }</span>
+<span class="source-line-no">1042</span><span id="line-1042">    }</span>
+<span class="source-line-no">1043</span><span id="line-1043">    // Let the next() call handle re-creating and seeking</span>
+<span class="source-line-no">1044</span><span id="line-1044">  }</span>
+<span class="source-line-no">1045</span><span id="line-1045"></span>
+<span class="source-line-no">1046</span><span id="line-1046">  /** Returns if top of heap has changed (and KeyValueHeap has to try the next KV) */</span>
+<span class="source-line-no">1047</span><span id="line-1047">  protected final boolean reopenAfterFlush() throws IOException {</span>
+<span class="source-line-no">1048</span><span id="line-1048">    // here we can make sure that we have a Store instance so no null check on store.</span>
+<span class="source-line-no">1049</span><span id="line-1049">    ExtendedCell lastTop = heap.peek();</span>
+<span class="source-line-no">1050</span><span id="line-1050">    // When we have the scan object, should we not pass it to getScanners() to get a limited set of</span>
+<span class="source-line-no">1051</span><span id="line-1051">    // scanners? We did so in the constructor and we could have done it now by storing the scan</span>
+<span class="source-line-no">1052</span><span id="line-1052">    // object from the constructor</span>
+<span class="source-line-no">1053</span><span id="line-1053">    List&lt;KeyValueScanner&gt; scanners;</span>
+<span class="source-line-no">1054</span><span id="line-1054">    flushLock.lock();</span>
+<span class="source-line-no">1055</span><span id="line-1055">    try {</span>
+<span class="source-line-no">1056</span><span id="line-1056">      List&lt;KeyValueScanner&gt; allScanners =</span>
+<span class="source-line-no">1057</span><span id="line-1057">        new ArrayList&lt;&gt;(flushedstoreFileScanners.size() + memStoreScannersAfterFlush.size());</span>
+<span class="source-line-no">1058</span><span id="line-1058">      allScanners.addAll(flushedstoreFileScanners);</span>
+<span class="source-line-no">1059</span><span id="line-1059">      allScanners.addAll(memStoreScannersAfterFlush);</span>
+<span class="source-line-no">1060</span><span id="line-1060">      scanners = selectScannersFrom(store, allScanners);</span>
+<span class="source-line-no">1061</span><span id="line-1061">      // Clear the current set of flushed store files scanners so that they don't get added again</span>
+<span class="source-line-no">1062</span><span id="line-1062">      flushedstoreFileScanners.clear();</span>
+<span class="source-line-no">1063</span><span id="line-1063">      memStoreScannersAfterFlush.clear();</span>
+<span class="source-line-no">1064</span><span id="line-1064">    } finally {</span>
+<span class="source-line-no">1065</span><span id="line-1065">      flushLock.unlock();</span>
+<span class="source-line-no">1066</span><span id="line-1066">    }</span>
+<span class="source-line-no">1067</span><span id="line-1067"></span>
+<span class="source-line-no">1068</span><span id="line-1068">    // Seek the new scanners to the last key</span>
+<span class="source-line-no">1069</span><span id="line-1069">    seekScanners(scanners, lastTop, false, parallelSeekEnabled);</span>
+<span class="source-line-no">1070</span><span id="line-1070">    // remove the older memstore scanner</span>
+<span class="source-line-no">1071</span><span id="line-1071">    for (int i = currentScanners.size() - 1; i &gt;= 0; i--) {</span>
+<span class="source-line-no">1072</span><span id="line-1072">      if (!currentScanners.get(i).isFileScanner()) {</span>
+<span class="source-line-no">1073</span><span id="line-1073">        scannersForDelayedClose.add(currentScanners.remove(i));</span>
+<span class="source-line-no">1074</span><span id="line-1074">      } else {</span>
+<span class="source-line-no">1075</span><span id="line-1075">        // we add the memstore scanner to the end of currentScanners</span>
+<span class="source-line-no">1076</span><span id="line-1076">        break;</span>
+<span class="source-line-no">1077</span><span id="line-1077">      }</span>
+<span class="source-line-no">1078</span><span id="line-1078">    }</span>
+<span class="source-line-no">1079</span><span id="line-1079">    // add the newly created scanners on the flushed files and the current active memstore scanner</span>
+<span class="source-line-no">1080</span><span id="line-1080">    addCurrentScanners(scanners);</span>
+<span class="source-line-no">1081</span><span id="line-1081">    // Combine all seeked scanners with a heap</span>
+<span class="source-line-no">1082</span><span id="line-1082">    resetKVHeap(this.currentScanners, store.getComparator());</span>
+<span class="source-line-no">1083</span><span id="line-1083">    resetQueryMatcher(lastTop);</span>
+<span class="source-line-no">1084</span><span id="line-1084">    if (heap.peek() == null || store.getComparator().compareRows(lastTop, this.heap.peek()) != 0) {</span>
+<span class="source-line-no">1085</span><span id="line-1085">      LOG.info("Storescanner.peek() is changed where before = " + lastTop.toString()</span>
+<span class="source-line-no">1086</span><span id="line-1086">        + ",and after = " + heap.peek());</span>
+<span class="source-line-no">1087</span><span id="line-1087">      topChanged = true;</span>
+<span class="source-line-no">1088</span><span id="line-1088">    } else {</span>
+<span class="source-line-no">1089</span><span id="line-1089">      topChanged = false;</span>
+<span class="source-line-no">1090</span><span id="line-1090">    }</span>
+<span class="source-line-no">1091</span><span id="line-1091">    return topChanged;</span>
+<span class="source-line-no">1092</span><span id="line-1092">  }</span>
+<span class="source-line-no">1093</span><span id="line-1093"></span>
+<span class="source-line-no">1094</span><span id="line-1094">  private void resetQueryMatcher(ExtendedCell lastTopKey) {</span>
+<span class="source-line-no">1095</span><span id="line-1095">    // Reset the state of the Query Matcher and set to top row.</span>
+<span class="source-line-no">1096</span><span id="line-1096">    // Only reset and call setRow if the row changes; avoids confusing the</span>
+<span class="source-line-no">1097</span><span id="line-1097">    // query matcher if scanning intra-row.</span>
+<span class="source-line-no">1098</span><span id="line-1098">    ExtendedCell cell = heap.peek();</span>
+<span class="source-line-no">1099</span><span id="line-1099">    if (cell == null) {</span>
+<span class="source-line-no">1100</span><span id="line-1100">      cell = lastTopKey;</span>
+<span class="source-line-no">1101</span><span id="line-1101">    }</span>
+<span class="source-line-no">1102</span><span id="line-1102">    if ((matcher.currentRow() == null) || !CellUtil.matchingRows(cell, matcher.currentRow())) {</span>
+<span class="source-line-no">1103</span><span id="line-1103">      this.countPerRow = 0;</span>
+<span class="source-line-no">1104</span><span id="line-1104">      // The setToNewRow will call reset internally</span>
+<span class="source-line-no">1105</span><span id="line-1105">      matcher.setToNewRow(cell);</span>
+<span class="source-line-no">1106</span><span id="line-1106">    }</span>
+<span class="source-line-no">1107</span><span id="line-1107">  }</span>
+<span class="source-line-no">1108</span><span id="line-1108"></span>
+<span class="source-line-no">1109</span><span id="line-1109">  /**</span>
+<span class="source-line-no">1110</span><span id="line-1110">   * Check whether scan as expected order</span>
+<span class="source-line-no">1111</span><span id="line-1111">   */</span>
+<span class="source-line-no">1112</span><span id="line-1112">  protected void checkScanOrder(Cell prevKV, Cell kv, CellComparator comparator)</span>
+<span class="source-line-no">1113</span><span id="line-1113">    throws IOException {</span>
+<span class="source-line-no">1114</span><span id="line-1114">    // Check that the heap gives us KVs in an increasing order.</span>
+<span class="source-line-no">1115</span><span id="line-1115">    assert prevKV == null || comparator == null || comparator.compare(prevKV, kv) &lt;= 0</span>
+<span class="source-line-no">1116</span><span id="line-1116">      : "Key " + prevKV + " followed by a smaller key " + kv + " in cf " + store;</span>
+<span class="source-line-no">1117</span><span id="line-1117">  }</span>
+<span class="source-line-no">1118</span><span id="line-1118"></span>
+<span class="source-line-no">1119</span><span id="line-1119">  protected boolean seekToNextRow(ExtendedCell c) throws IOException {</span>
+<span class="source-line-no">1120</span><span id="line-1120">    return reseek(PrivateCellUtil.createLastOnRow(c));</span>
+<span class="source-line-no">1121</span><span id="line-1121">  }</span>
+<span class="source-line-no">1122</span><span id="line-1122"></span>
+<span class="source-line-no">1123</span><span id="line-1123">  /**</span>
+<span class="source-line-no">1124</span><span id="line-1124">   * Do a reseek in a normal StoreScanner(scan forward)</span>
+<span class="source-line-no">1125</span><span id="line-1125">   * @return true if scanner has values left, false if end of scanner</span>
+<span class="source-line-no">1126</span><span id="line-1126">   */</span>
+<span class="source-line-no">1127</span><span id="line-1127">  protected boolean seekAsDirection(ExtendedCell kv) throws IOException {</span>
+<span class="source-line-no">1128</span><span id="line-1128">    return reseek(kv);</span>
+<span class="source-line-no">1129</span><span id="line-1129">  }</span>
+<span class="source-line-no">1130</span><span id="line-1130"></span>
+<span class="source-line-no">1131</span><span id="line-1131">  @Override</span>
+<span class="source-line-no">1132</span><span id="line-1132">  public boolean reseek(ExtendedCell kv) throws IOException {</span>
+<span class="source-line-no">1133</span><span id="line-1133">    if (checkFlushed()) {</span>
+<span class="source-line-no">1134</span><span id="line-1134">      reopenAfterFlush();</span>
+<span class="source-line-no">1135</span><span id="line-1135">    }</span>
+<span class="source-line-no">1136</span><span id="line-1136">    if (explicitColumnQuery &amp;&amp; lazySeekEnabledGlobally) {</span>
+<span class="source-line-no">1137</span><span id="line-1137">      return heap.requestSeek(kv, true, useRowColBloom);</span>
+<span class="source-line-no">1138</span><span id="line-1138">    }</span>
+<span class="source-line-no">1139</span><span id="line-1139">    return heap.reseek(kv);</span>
+<span class="source-line-no">1140</span><span id="line-1140">  }</span>
+<span class="source-line-no">1141</span><span id="line-1141"></span>
+<span class="source-line-no">1142</span><span id="line-1142">  void trySwitchToStreamRead() {</span>
+<span class="source-line-no">1143</span><span id="line-1143">    if (</span>
+<span class="source-line-no">1144</span><span id="line-1144">      readType != Scan.ReadType.DEFAULT || !scanUsePread || closing || heap.peek() == null</span>
+<span class="source-line-no">1145</span><span id="line-1145">        || bytesRead &lt; preadMaxBytes</span>
+<span class="source-line-no">1146</span><span id="line-1146">    ) {</span>
+<span class="source-line-no">1147</span><span id="line-1147">      return;</span>
+<span class="source-line-no">1148</span><span id="line-1148">    }</span>
+<span class="source-line-no">1149</span><span id="line-1149">    LOG.debug("Switch to stream read (scanned={} bytes) of {}", bytesRead,</span>
+<span class="source-line-no">1150</span><span id="line-1150">      this.store.getColumnFamilyName());</span>
+<span class="source-line-no">1151</span><span id="line-1151">    scanUsePread = false;</span>
+<span class="source-line-no">1152</span><span id="line-1152">    ExtendedCell lastTop = heap.peek();</span>
+<span class="source-line-no">1153</span><span id="line-1153">    List&lt;KeyValueScanner&gt; memstoreScanners = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">1154</span><span id="line-1154">    List&lt;KeyValueScanner&gt; scannersToClose = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">1155</span><span id="line-1155">    for (KeyValueScanner kvs : currentScanners) {</span>
+<span class="source-line-no">1156</span><span id="line-1156">      if (!kvs.isFileScanner()) {</span>
+<span class="source-line-no">1157</span><span id="line-1157">        // collect memstorescanners here</span>
+<span class="source-line-no">1158</span><span id="line-1158">        memstoreScanners.add(kvs);</span>
+<span class="source-line-no">1159</span><span id="line-1159">      } else {</span>
+<span class="source-line-no">1160</span><span id="line-1160">        scannersToClose.add(kvs);</span>
+<span class="source-line-no">1161</span><span id="line-1161">      }</span>
+<span class="source-line-no">1162</span><span id="line-1162">    }</span>
+<span class="source-line-no">1163</span><span id="line-1163">    List&lt;KeyValueScanner&gt; fileScanners = null;</span>
+<span class="source-line-no">1164</span><span id="line-1164">    List&lt;KeyValueScanner&gt; newCurrentScanners;</span>
+<span class="source-line-no">1165</span><span id="line-1165">    KeyValueHeap newHeap;</span>
+<span class="source-line-no">1166</span><span id="line-1166">    try {</span>
+<span class="source-line-no">1167</span><span id="line-1167">      // We must have a store instance here so no null check</span>
+<span class="source-line-no">1168</span><span id="line-1168">      // recreate the scanners on the current file scanners</span>
+<span class="source-line-no">1169</span><span id="line-1169">      fileScanners = store.recreateScanners(scannersToClose, cacheBlocks, false, false, matcher,</span>
+<span class="source-line-no">1170</span><span id="line-1170">        scan.getStartRow(), scan.includeStartRow(), scan.getStopRow(), scan.includeStopRow(),</span>
+<span class="source-line-no">1171</span><span id="line-1171">        readPt, false);</span>
+<span class="source-line-no">1172</span><span id="line-1172">      if (fileScanners == null) {</span>
+<span class="source-line-no">1173</span><span id="line-1173">        return;</span>
+<span class="source-line-no">1174</span><span id="line-1174">      }</span>
+<span class="source-line-no">1175</span><span id="line-1175">      seekScanners(fileScanners, lastTop, false, parallelSeekEnabled);</span>
+<span class="source-line-no">1176</span><span id="line-1176">      newCurrentScanners = new ArrayList&lt;&gt;(fileScanners.size() + memstoreScanners.size());</span>
+<span class="source-line-no">1177</span><span id="line-1177">      newCurrentScanners.addAll(fileScanners);</span>
+<span class="source-line-no">1178</span><span id="line-1178">      newCurrentScanners.addAll(memstoreScanners);</span>
+<span class="source-line-no">1179</span><span id="line-1179">      newHeap = newKVHeap(newCurrentScanners, comparator);</span>
+<span class="source-line-no">1180</span><span id="line-1180">    } catch (Exception e) {</span>
+<span class="source-line-no">1181</span><span id="line-1181">      LOG.warn("failed to switch to stream read", e);</span>
+<span class="source-line-no">1182</span><span id="line-1182">      if (fileScanners != null) {</span>
+<span class="source-line-no">1183</span><span id="line-1183">        fileScanners.forEach(KeyValueScanner::close);</span>
+<span class="source-line-no">1184</span><span id="line-1184">      }</span>
+<span class="source-line-no">1185</span><span id="line-1185">      return;</span>
+<span class="source-line-no">1186</span><span id="line-1186">    }</span>
+<span class="source-line-no">1187</span><span id="line-1187">    currentScanners.clear();</span>
+<span class="source-line-no">1188</span><span id="line-1188">    addCurrentScanners(newCurrentScanners);</span>
+<span class="source-line-no">1189</span><span id="line-1189">    this.heap = newHeap;</span>
+<span class="source-line-no">1190</span><span id="line-1190">    resetQueryMatcher(lastTop);</span>
+<span class="source-line-no">1191</span><span id="line-1191">    scannersToClose.forEach(KeyValueScanner::close);</span>
+<span class="source-line-no">1192</span><span id="line-1192">    if (hasSwitchedToStreamRead != null) {</span>
+<span class="source-line-no">1193</span><span id="line-1193">      hasSwitchedToStreamRead.set(true);</span>
+<span class="source-line-no">1194</span><span id="line-1194">    }</span>
+<span class="source-line-no">1195</span><span id="line-1195">  }</span>
+<span class="source-line-no">1196</span><span id="line-1196"></span>
+<span class="source-line-no">1197</span><span id="line-1197">  protected final boolean checkFlushed() {</span>
+<span class="source-line-no">1198</span><span id="line-1198">    // check the var without any lock. Suppose even if we see the old</span>
+<span class="source-line-no">1199</span><span id="line-1199">    // value here still it is ok to continue because we will not be resetting</span>
+<span class="source-line-no">1200</span><span id="line-1200">    // the heap but will continue with the referenced memstore's snapshot. For compactions</span>
+<span class="source-line-no">1201</span><span id="line-1201">    // any way we don't need the updateReaders at all to happen as we still continue with</span>
+<span class="source-line-no">1202</span><span id="line-1202">    // the older files</span>
+<span class="source-line-no">1203</span><span id="line-1203">    if (flushed) {</span>
+<span class="source-line-no">1204</span><span id="line-1204">      // If there is a flush and the current scan is notified on the flush ensure that the</span>
+<span class="source-line-no">1205</span><span id="line-1205">      // scan's heap gets reset and we do a seek on the newly flushed file.</span>
+<span class="source-line-no">1206</span><span id="line-1206">      if (this.closing) {</span>
+<span class="source-line-no">1207</span><span id="line-1207">        return false;</span>
+<span class="source-line-no">1208</span><span id="line-1208">      }</span>
+<span class="source-line-no">1209</span><span id="line-1209">      // reset the flag</span>
+<span class="source-line-no">1210</span><span id="line-1210">      flushed = false;</span>
+<span class="source-line-no">1211</span><span id="line-1211">      return true;</span>
+<span class="source-line-no">1212</span><span id="line-1212">    }</span>
+<span class="source-line-no">1213</span><span id="line-1213">    return false;</span>
+<span class="source-line-no">1214</span><span id="line-1214">  }</span>
+<span class="source-line-no">1215</span><span id="line-1215"></span>
+<span class="source-line-no">1216</span><span id="line-1216">  /**</span>
+<span class="source-line-no">1217</span><span id="line-1217">   * Seek storefiles in parallel to optimize IO latency as much as possible</span>
+<span class="source-line-no">1218</span><span id="line-1218">   * @param scanners the list {@link KeyValueScanner}s to be read from</span>
+<span class="source-line-no">1219</span><span id="line-1219">   * @param kv       the KeyValue on which the operation is being requested</span>
+<span class="source-line-no">1220</span><span id="line-1220">   */</span>
+<span class="source-line-no">1221</span><span id="line-1221">  private void parallelSeek(final List&lt;? extends KeyValueScanner&gt; scanners, final ExtendedCell kv)</span>
+<span class="source-line-no">1222</span><span id="line-1222">    throws IOException {</span>
+<span class="source-line-no">1223</span><span id="line-1223">    if (scanners.isEmpty()) return;</span>
+<span class="source-line-no">1224</span><span id="line-1224">    int storeFileScannerCount = scanners.size();</span>
+<span class="source-line-no">1225</span><span id="line-1225">    CountDownLatch latch = new CountDownLatch(storeFileScannerCount);</span>
+<span class="source-line-no">1226</span><span id="line-1226">    List&lt;ParallelSeekHandler&gt; handlers = new ArrayList&lt;&gt;(storeFileScannerCount);</span>
+<span class="source-line-no">1227</span><span id="line-1227">    for (KeyValueScanner scanner : scanners) {</span>
+<span class="source-line-no">1228</span><span id="line-1228">      if (scanner instanceof StoreFileScanner) {</span>
+<span class="source-line-no">1229</span><span id="line-1229">        ParallelSeekHandler seekHandler = new ParallelSeekHandler(scanner, kv, this.readPt, latch);</span>
+<span class="source-line-no">1230</span><span id="line-1230">        executor.submit(seekHandler);</span>
+<span class="source-line-no">1231</span><span id="line-1231">        handlers.add(seekHandler);</span>
+<span class="source-line-no">1232</span><span id="line-1232">      } else {</span>
+<span class="source-line-no">1233</span><span id="line-1233">        scanner.seek(kv);</span>
+<span class="source-line-no">1234</span><span id="line-1234">        latch.countDown();</span>
+<span class="source-line-no">1235</span><span id="line-1235">      }</span>
+<span class="source-line-no">1236</span><span id="line-1236">    }</span>
+<span class="source-line-no">1237</span><span id="line-1237"></span>
+<span class="source-line-no">1238</span><span id="line-1238">    try {</span>
+<span class="source-line-no">1239</span><span id="line-1239">      latch.await();</span>
+<span class="source-line-no">1240</span><span id="line-1240">    } catch (InterruptedException ie) {</span>
+<span class="source-line-no">1241</span><span id="line-1241">      throw (InterruptedIOException) new InterruptedIOException().initCause(ie);</span>
+<span class="source-line-no">1242</span><span id="line-1242">    }</span>
+<span class="source-line-no">1243</span><span id="line-1243"></span>
+<span class="source-line-no">1244</span><span id="line-1244">    for (ParallelSeekHandler handler : handlers) {</span>
+<span class="source-line-no">1245</span><span id="line-1245">      if (handler.getErr() != null) {</span>
+<span class="source-line-no">1246</span><span id="line-1246">        throw new IOException(handler.getErr());</span>
+<span class="source-line-no">1247</span><span id="line-1247">      }</span>
+<span class="source-line-no">1248</span><span id="line-1248">    }</span>
+<span class="source-line-no">1249</span><span id="line-1249">  }</span>
+<span class="source-line-no">1250</span><span id="line-1250"></span>
+<span class="source-line-no">1251</span><span id="line-1251">  /**</span>
+<span class="source-line-no">1252</span><span id="line-1252">   * Used in testing.</span>
+<span class="source-line-no">1253</span><span id="line-1253">   * @return all scanners in no particular order</span>
+<span class="source-line-no">1254</span><span id="line-1254">   */</span>
+<span class="source-line-no">1255</span><span id="line-1255">  List&lt;KeyValueScanner&gt; getAllScannersForTesting() {</span>
+<span class="source-line-no">1256</span><span id="line-1256">    List&lt;KeyValueScanner&gt; allScanners = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">1257</span><span id="line-1257">    KeyValueScanner current = heap.getCurrentForTesting();</span>
+<span class="source-line-no">1258</span><span id="line-1258">    if (current != null) allScanners.add(current);</span>
+<span class="source-line-no">1259</span><span id="line-1259">    for (KeyValueScanner scanner : heap.getHeap())</span>
+<span class="source-line-no">1260</span><span id="line-1260">      allScanners.add(scanner);</span>
+<span class="source-line-no">1261</span><span id="line-1261">    return allScanners;</span>
+<span class="source-line-no">1262</span><span id="line-1262">  }</span>
+<span class="source-line-no">1263</span><span id="line-1263"></span>
+<span class="source-line-no">1264</span><span id="line-1264">  static void enableLazySeekGlobally(boolean enable) {</span>
+<span class="source-line-no">1265</span><span id="line-1265">    lazySeekEnabledGlobally = enable;</span>
+<span class="source-line-no">1266</span><span id="line-1266">  }</span>
+<span class="source-line-no">1267</span><span id="line-1267"></span>
+<span class="source-line-no">1268</span><span id="line-1268">  /** Returns The estimated number of KVs seen by this scanner (includes some skipped KVs). */</span>
+<span class="source-line-no">1269</span><span id="line-1269">  public long getEstimatedNumberOfKvsScanned() {</span>
+<span class="source-line-no">1270</span><span id="line-1270">    return this.kvsScanned;</span>
+<span class="source-line-no">1271</span><span id="line-1271">  }</span>
+<span class="source-line-no">1272</span><span id="line-1272"></span>
+<span class="source-line-no">1273</span><span id="line-1273">  @Override</span>
+<span class="source-line-no">1274</span><span id="line-1274">  public ExtendedCell getNextIndexedKey() {</span>
+<span class="source-line-no">1275</span><span id="line-1275">    return this.heap.getNextIndexedKey();</span>
+<span class="source-line-no">1276</span><span id="line-1276">  }</span>
+<span class="source-line-no">1277</span><span id="line-1277"></span>
+<span class="source-line-no">1278</span><span id="line-1278">  @Override</span>
+<span class="source-line-no">1279</span><span id="line-1279">  public void shipped() throws IOException {</span>
+<span class="source-line-no">1280</span><span id="line-1280">    if (prevCell != null) {</span>
+<span class="source-line-no">1281</span><span id="line-1281">      // Do the copy here so that in case the prevCell ref is pointing to the previous</span>
+<span class="source-line-no">1282</span><span id="line-1282">      // blocks we can safely release those blocks.</span>
+<span class="source-line-no">1283</span><span id="line-1283">      // This applies to blocks that are got from Bucket cache, L1 cache and the blocks</span>
+<span class="source-line-no">1284</span><span id="line-1284">      // fetched from HDFS. Copying this would ensure that we let go the references to these</span>
+<span class="source-line-no">1285</span><span id="line-1285">      // blocks so that they can be GCed safely(in case of bucket cache)</span>
+<span class="source-line-no">1286</span><span id="line-1286">      prevCell = KeyValueUtil.toNewKeyCell(this.prevCell);</span>
+<span class="source-line-no">1287</span><span id="line-1287">    }</span>
+<span class="source-line-no">1288</span><span id="line-1288">    matcher.beforeShipped();</span>
+<span class="source-line-no">1289</span><span id="line-1289">    // There wont be further fetch of Cells from these scanners. Just close.</span>
+<span class="source-line-no">1290</span><span id="line-1290">    clearAndClose(scannersForDelayedClose);</span>
+<span class="source-line-no">1291</span><span id="line-1291">    if (this.heap != null) {</span>
+<span class="source-line-no">1292</span><span id="line-1292">      this.heap.shipped();</span>
+<span class="source-line-no">1293</span><span id="line-1293">      // When switching from pread to stream, we will open a new scanner for each store file, but</span>
+<span class="source-line-no">1294</span><span id="line-1294">      // the old scanner may still track the HFileBlocks we have scanned but not sent back to client</span>
+<span class="source-line-no">1295</span><span id="line-1295">      // yet. If we close the scanner immediately then the HFileBlocks may be messed up by others</span>
+<span class="source-line-no">1296</span><span id="line-1296">      // before we serialize and send it back to client. The HFileBlocks will be released in shipped</span>
+<span class="source-line-no">1297</span><span id="line-1297">      // method, so we here will also open new scanners and close old scanners in shipped method.</span>
+<span class="source-line-no">1298</span><span id="line-1298">      // See HBASE-18055 for more details.</span>
+<span class="source-line-no">1299</span><span id="line-1299">      trySwitchToStreamRead();</span>
+<span class="source-line-no">1300</span><span id="line-1300">    }</span>
+<span class="source-line-no">1301</span><span id="line-1301">  }</span>
+<span class="source-line-no">1302</span><span id="line-1302"></span>
+<span class="source-line-no">1303</span><span id="line-1303">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
+<span class="source-line-no">1304</span><span id="line-1304">  static final void instrument() {</span>
+<span class="source-line-no">1305</span><span id="line-1305">    hasUpdatedReaders = new AtomicBoolean(false);</span>
+<span class="source-line-no">1306</span><span id="line-1306">    hasSwitchedToStreamRead = new AtomicBoolean(false);</span>
+<span class="source-line-no">1307</span><span id="line-1307">  }</span>
+<span class="source-line-no">1308</span><span id="line-1308"></span>
+<span class="source-line-no">1309</span><span id="line-1309">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
+<span class="source-line-no">1310</span><span id="line-1310">  static final boolean hasUpdatedReaders() {</span>
+<span class="source-line-no">1311</span><span id="line-1311">    return hasUpdatedReaders.get();</span>
+<span class="source-line-no">1312</span><span id="line-1312">  }</span>
+<span class="source-line-no">1313</span><span id="line-1313"></span>
+<span class="source-line-no">1314</span><span id="line-1314">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
+<span class="source-line-no">1315</span><span id="line-1315">  static final boolean hasSwitchedToStreamRead() {</span>
+<span class="source-line-no">1316</span><span id="line-1316">    return hasSwitchedToStreamRead.get();</span>
+<span class="source-line-no">1317</span><span id="line-1317">  }</span>
+<span class="source-line-no">1318</span><span id="line-1318"></span>
+<span class="source-line-no">1319</span><span id="line-1319">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
+<span class="source-line-no">1320</span><span id="line-1320">  static final void resetHasUpdatedReaders() {</span>
+<span class="source-line-no">1321</span><span id="line-1321">    hasUpdatedReaders.set(false);</span>
+<span class="source-line-no">1322</span><span id="line-1322">  }</span>
+<span class="source-line-no">1323</span><span id="line-1323"></span>
+<span class="source-line-no">1324</span><span id="line-1324">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
+<span class="source-line-no">1325</span><span id="line-1325">  static final void resetHasSwitchedToStreamRead() {</span>
+<span class="source-line-no">1326</span><span id="line-1326">    hasSwitchedToStreamRead.set(false);</span>
+<span class="source-line-no">1327</span><span id="line-1327">  }</span>
+<span class="source-line-no">1328</span><span id="line-1328">}</span>
 
 
 
diff --git a/book.html b/book.html
index 6f7c154931e..804d3e3d70f 100644
--- a/book.html
+++ b/book.html
@@ -50192,7 +50192,7 @@ org/apache/hadoop/hbase/security/access/AccessControlClient.revoke:(Lorg/apache/
 <div id="footer">
 <div id="footer-text">
 Version 4.0.0-alpha-1-SNAPSHOT<br>
-Last updated 2026-02-25 14:31:29 UTC
+Last updated 2026-02-26 14:31:22 UTC
 </div>
 </div>
 <script type="text/x-mathjax-config">
diff --git a/checkstyle-aggregate.html b/checkstyle-aggregate.html
index 9244f4d1a6d..7559fccce78 100644
--- a/checkstyle-aggregate.html
+++ b/checkstyle-aggregate.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-checkstyle-plugin:3.6.0:checkstyle-aggregate at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-checkstyle-plugin:3.6.0:checkstyle-aggregate at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
@@ -14231,19 +14231,19 @@
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>1225</td></tr>
+<td>1223</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>1260</td></tr>
+<td>1258</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'for' construct must use '{}'s.</td>
-<td>1261</td></tr></table></section><section><a id="org.2Fapache.2Fhadoop.2Fhbase.2Fregionserver.2FStorefileRefresherChore.java"></a>
+<td>1259</td></tr></table></section><section><a id="org.2Fapache.2Fhadoop.2Fhbase.2Fregionserver.2FStorefileRefresherChore.java"></a>
 <h3>org/apache/hadoop/hbase/regionserver/StorefileRefresherChore.java</h3>
 <table class="table table-striped">
 <tr class="a">
diff --git a/dependency-convergence.html b/dependency-convergence.html
index dcd41f2c1df..b9bf7a5743e 100644
--- a/dependency-convergence.html
+++ b/dependency-convergence.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-convergence at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-convergence at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/dependency-info.html b/dependency-info.html
index 30ef4698ac9..9bf5d46dc0c 100644
--- a/dependency-info.html
+++ b/dependency-info.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-info at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-info at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/dependency-management.html b/dependency-management.html
index 69b450a54d2..da5b51f9321 100644
--- a/dependency-management.html
+++ b/dependency-management.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-management at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-management at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/devapidocs/org/apache/hadoop/hbase/regionserver/StoreScanner.html b/devapidocs/org/apache/hadoop/hbase/regionserver/StoreScanner.html
index 991ffcf1998..80726b0f2f1 100644
--- a/devapidocs/org/apache/hadoop/hbase/regionserver/StoreScanner.html
+++ b/devapidocs/org/apache/hadoop/hbase/regionserver/StoreScanner.html
@@ -1370,7 +1370,7 @@ implements <a href="KeyValueScanner.html" title="interface in org.apache.hadoop.
 <li>
 <section class="detail" id="getReadPoint()">
 <h3>getReadPoint</h3>
-<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">long</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-976">getReadPoint</a></span>()</div>
+<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">long</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-974">getReadPoint</a></span>()</div>
 <div class="block"><span class="descfrm-type-label">Description copied from interface:&nbsp;<code><a href="ChangedReadersObserver.html#getReadPoint()">ChangedReadersObserver</a></code></span></div>
 <div class="block">Returns the read point of the current scan</div>
 <dl class="notes">
@@ -1382,13 +1382,13 @@ implements <a href="KeyValueScanner.html" title="interface in org.apache.hadoop.
 <li>
 <section class="detail" id="clearAndClose(java.util.List)">
 <h3>clearAndClose</h3>
-<div class="member-signature"><span class="modifiers">private static</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-981">clearAndClose</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;<a href="KeyValueScanne [...]
+<div class="member-signature"><span class="modifiers">private static</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-979">clearAndClose</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;<a href="KeyValueScanne [...]
 </section>
 </li>
 <li>
 <section class="detail" id="updateReaders(java.util.List,java.util.List)">
 <h3>updateReaders</h3>
-<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-992">updateReaders</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;<a href="HStoreFile.html" title [...]
+<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-990">updateReaders</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;<a href="HStoreFile.html" title [...]
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;<a href="KeyValueScanner.html" title="interface in org.apache.hadoop.hbase.regionserver">KeyValueScanner</a>&gt;&nbsp;memStoreScanners)</span>
                    throws <span class="exceptions"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/IOException.html" title="class or interface in java.io" class="external-link">IOException</a></span></div>
 <div class="block"><span class="descfrm-type-label">Description copied from interface:&nbsp;<code><a href="ChangedReadersObserver.html#updateReaders(java.util.List,java.util.List)">ChangedReadersObserver</a></code></span></div>
@@ -1413,7 +1413,7 @@ implements <a href="KeyValueScanner.html" title="interface in org.apache.hadoop.
 <li>
 <section class="detail" id="reopenAfterFlush()">
 <h3>reopenAfterFlush</h3>
-<div class="member-signature"><span class="modifiers">protected final</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1049">reopenAfterFlush</a></span>()
+<div class="member-signature"><span class="modifiers">protected final</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1047">reopenAfterFlush</a></span>()
                                   throws <span class="exceptions"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/IOException.html" title="class or interface in java.io" class="external-link">IOException</a></span></div>
 <div class="block">Returns if top of heap has changed (and KeyValueHeap has to try the next KV)</div>
 <dl class="notes">
@@ -1425,13 +1425,13 @@ implements <a href="KeyValueScanner.html" title="interface in org.apache.hadoop.
 <li>
 <section class="detail" id="resetQueryMatcher(org.apache.hadoop.hbase.ExtendedCell)">
 <h3>resetQueryMatcher</h3>
-<div class="member-signature"><span class="modifiers">private</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1096">resetQueryMatcher</a></span><wbr><span class="parameters">(<a href="../ExtendedCell.html" title="interface in org.apache.hadoop.hbase">ExtendedCell</a>&nbsp;lastTopKey)</span></div>
+<div class="member-signature"><span class="modifiers">private</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1094">resetQueryMatcher</a></span><wbr><span class="parameters">(<a href="../ExtendedCell.html" title="interface in org.apache.hadoop.hbase">ExtendedCell</a>&nbsp;lastTopKey)</span></div>
 </section>
 </li>
 <li>
 <section class="detail" id="checkScanOrder(org.apache.hadoop.hbase.Cell,org.apache.hadoop.hbase.Cell,org.apache.hadoop.hbase.CellComparator)">
 <h3>checkScanOrder</h3>
-<div class="member-signature"><span class="modifiers">protected</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1114">checkScanOrder</a></span><wbr><span class="parameters">(<a href="../Cell.html" title="interface in org.apache.hadoop.hbase">Cell</a>&nbsp;prevKV,
+<div class="member-signature"><span class="modifiers">protected</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1112">checkScanOrder</a></span><wbr><span class="parameters">(<a href="../Cell.html" title="interface in org.apache.hadoop.hbase">Cell</a>&nbsp;prevKV,
  <a href="../Cell.html" title="interface in org.apache.hadoop.hbase">Cell</a>&nbsp;kv,
  <a href="../CellComparator.html" title="interface in org.apache.hadoop.hbase">CellComparator</a>&nbsp;comparator)</span>
                        throws <span class="exceptions"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/IOException.html" title="class or interface in java.io" class="external-link">IOException</a></span></div>
@@ -1445,7 +1445,7 @@ implements <a href="KeyValueScanner.html" title="interface in org.apache.hadoop.
 <li>
 <section class="detail" id="seekToNextRow(org.apache.hadoop.hbase.ExtendedCell)">
 <h3>seekToNextRow</h3>
-<div class="member-signature"><span class="modifiers">protected</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1121">seekToNextRow</a></span><wbr><span class="parameters">(<a href="../ExtendedCell.html" title="interface in org.apache.hadoop.hbase">ExtendedCell</a>&nbsp;c)</span>
+<div class="member-signature"><span class="modifiers">protected</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1119">seekToNextRow</a></span><wbr><span class="parameters">(<a href="../ExtendedCell.html" title="interface in org.apache.hadoop.hbase">ExtendedCell</a>&nbsp;c)</span>
                          throws <span class="exceptions"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/IOException.html" title="class or interface in java.io" class="external-link">IOException</a></span></div>
 <dl class="notes">
 <dt>Throws:</dt>
@@ -1456,7 +1456,7 @@ implements <a href="KeyValueScanner.html" title="interface in org.apache.hadoop.
 <li>
 <section class="detail" id="seekAsDirection(org.apache.hadoop.hbase.ExtendedCell)">
 <h3>seekAsDirection</h3>
-<div class="member-signature"><span class="modifiers">protected</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1129">seekAsDirection</a></span><wbr><span class="parameters">(<a href="../ExtendedCell.html" title="interface in org.apache.hadoop.hbase">ExtendedCell</a>&nbsp;kv)</span>
+<div class="member-signature"><span class="modifiers">protected</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1127">seekAsDirection</a></span><wbr><span class="parameters">(<a href="../ExtendedCell.html" title="interface in org.apache.hadoop.hbase">ExtendedCell</a>&nbsp;kv)</span>
                            throws <span class="exceptions"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/IOException.html" title="class or interface in java.io" class="external-link">IOException</a></span></div>
 <div class="block">Do a reseek in a normal StoreScanner(scan forward)</div>
 <dl class="notes">
@@ -1470,7 +1470,7 @@ implements <a href="KeyValueScanner.html" title="interface in org.apache.hadoop.
 <li>
 <section class="detail" id="reseek(org.apache.hadoop.hbase.ExtendedCell)">
 <h3>reseek</h3>
-<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1133">reseek</a></span><wbr><span class="parameters">(<a href="../ExtendedCell.html" title="interface in org.apache.hadoop.hbase">ExtendedCell</a>&nbsp;kv)</span>
+<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1131">reseek</a></span><wbr><span class="parameters">(<a href="../ExtendedCell.html" title="interface in org.apache.hadoop.hbase">ExtendedCell</a>&nbsp;kv)</span>
                throws <span class="exceptions"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/IOException.html" title="class or interface in java.io" class="external-link">IOException</a></span></div>
 <div class="block"><span class="descfrm-type-label">Description copied from interface:&nbsp;<code><a href="KeyValueScanner.html#reseek(org.apache.hadoop.hbase.ExtendedCell)">KeyValueScanner</a></code></span></div>
 <div class="block">Reseek the scanner at or after the specified KeyValue. This method is guaranteed to seek at or
@@ -1491,19 +1491,19 @@ implements <a href="KeyValueScanner.html" title="interface in org.apache.hadoop.
 <li>
 <section class="detail" id="trySwitchToStreamRead()">
 <h3>trySwitchToStreamRead</h3>
-<div class="member-signature"><span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1144">trySwitchToStreamRead</a></span>()</div>
+<div class="member-signature"><span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1142">trySwitchToStreamRead</a></span>()</div>
 </section>
 </li>
 <li>
 <section class="detail" id="checkFlushed()">
 <h3>checkFlushed</h3>
-<div class="member-signature"><span class="modifiers">protected final</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1199">checkFlushed</a></span>()</div>
+<div class="member-signature"><span class="modifiers">protected final</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1197">checkFlushed</a></span>()</div>
 </section>
 </li>
 <li>
 <section class="detail" id="parallelSeek(java.util.List,org.apache.hadoop.hbase.ExtendedCell)">
 <h3>parallelSeek</h3>
-<div class="member-signature"><span class="modifiers">private</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1223">parallelSeek</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;? extends <a href="KeyValueSca [...]
+<div class="member-signature"><span class="modifiers">private</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1221">parallelSeek</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;? extends <a href="KeyValueSca [...]
  <a href="../ExtendedCell.html" title="interface in org.apache.hadoop.hbase">ExtendedCell</a>&nbsp;kv)</span>
                    throws <span class="exceptions"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/IOException.html" title="class or interface in java.io" class="external-link">IOException</a></span></div>
 <div class="block">Seek storefiles in parallel to optimize IO latency as much as possible</div>
@@ -1519,7 +1519,7 @@ implements <a href="KeyValueScanner.html" title="interface in org.apache.hadoop.
 <li>
 <section class="detail" id="getAllScannersForTesting()">
 <h3>getAllScannersForTesting</h3>
-<div class="member-signature"><span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;<a href="KeyValueScanner.html" title="interface in org.apache.hadoop.hbase.regionserver">KeyValueScanner</a>&gt;</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1257">getAllScannersForTes [...]
+<div class="member-signature"><span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;<a href="KeyValueScanner.html" title="interface in org.apache.hadoop.hbase.regionserver">KeyValueScanner</a>&gt;</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1255">getAllScannersForTes [...]
 <div class="block">Used in testing.</div>
 <dl class="notes">
 <dt>Returns:</dt>
@@ -1530,20 +1530,20 @@ implements <a href="KeyValueScanner.html" title="interface in org.apache.hadoop.
 <li>
 <section class="detail" id="enableLazySeekGlobally(boolean)">
 <h3>enableLazySeekGlobally</h3>
-<div class="member-signature"><span class="modifiers">static</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1266">enableLazySeekGlobally</a></span><wbr><span class="parameters">(boolean&nbsp;enable)</span></div>
+<div class="member-signature"><span class="modifiers">static</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1264">enableLazySeekGlobally</a></span><wbr><span class="parameters">(boolean&nbsp;enable)</span></div>
 </section>
 </li>
 <li>
 <section class="detail" id="getEstimatedNumberOfKvsScanned()">
 <h3>getEstimatedNumberOfKvsScanned</h3>
-<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">long</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1271">getEstimatedNumberOfKvsScanned</a></span>()</div>
+<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">long</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1269">getEstimatedNumberOfKvsScanned</a></span>()</div>
 <div class="block">Returns The estimated number of KVs seen by this scanner (includes some skipped KVs).</div>
 </section>
 </li>
 <li>
 <section class="detail" id="getNextIndexedKey()">
 <h3>getNextIndexedKey</h3>
-<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="../ExtendedCell.html" title="interface in org.apache.hadoop.hbase">ExtendedCell</a></span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1275">getNextIndexedKey</a></span>()</div>
+<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="../ExtendedCell.html" title="interface in org.apache.hadoop.hbase">ExtendedCell</a></span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1273">getNextIndexedKey</a></span>()</div>
 <dl class="notes">
 <dt>Specified by:</dt>
 <dd><code><a href="KeyValueScanner.html#getNextIndexedKey()">getNextIndexedKey</a></code>&nbsp;in interface&nbsp;<code><a href="KeyValueScanner.html" title="interface in org.apache.hadoop.hbase.regionserver">KeyValueScanner</a></code></dd>
@@ -1559,7 +1559,7 @@ implements <a href="KeyValueScanner.html" title="interface in org.apache.hadoop.
 <li>
 <section class="detail" id="shipped()">
 <h3>shipped</h3>
-<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1280">shipped</a></span>()
+<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1278">shipped</a></span>()
              throws <span class="exceptions"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/IOException.html" title="class or interface in java.io" class="external-link">IOException</a></span></div>
 <div class="block"><span class="descfrm-type-label">Description copied from interface:&nbsp;<code><a href="Shipper.html#shipped()">Shipper</a></code></span></div>
 <div class="block">Called after a batch of rows scanned and set to be returned to client. Any in between cleanup
@@ -1578,35 +1578,35 @@ implements <a href="KeyValueScanner.html" title="interface in org.apache.hadoop.
 <section class="detail" id="instrument()">
 <h3>instrument</h3>
 <div class="member-signature"><span class="annotations">@LimitedPrivate("Unittest")
-</span><span class="modifiers">static final</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1305">instrument</a></span>()</div>
+</span><span class="modifiers">static final</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1303">instrument</a></span>()</div>
 </section>
 </li>
 <li>
 <section class="detail" id="hasUpdatedReaders()">
 <h3>hasUpdatedReaders</h3>
 <div class="member-signature"><span class="annotations">@LimitedPrivate("Unittest")
-</span><span class="modifiers">static final</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1311">hasUpdatedReaders</a></span>()</div>
+</span><span class="modifiers">static final</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1309">hasUpdatedReaders</a></span>()</div>
 </section>
 </li>
 <li>
 <section class="detail" id="hasSwitchedToStreamRead()">
 <h3>hasSwitchedToStreamRead</h3>
 <div class="member-signature"><span class="annotations">@LimitedPrivate("Unittest")
-</span><span class="modifiers">static final</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1316">hasSwitchedToStreamRead</a></span>()</div>
+</span><span class="modifiers">static final</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1314">hasSwitchedToStreamRead</a></span>()</div>
 </section>
 </li>
 <li>
 <section class="detail" id="resetHasUpdatedReaders()">
 <h3>resetHasUpdatedReaders</h3>
 <div class="member-signature"><span class="annotations">@LimitedPrivate("Unittest")
-</span><span class="modifiers">static final</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1321">resetHasUpdatedReaders</a></span>()</div>
+</span><span class="modifiers">static final</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1319">resetHasUpdatedReaders</a></span>()</div>
 </section>
 </li>
 <li>
 <section class="detail" id="resetHasSwitchedToStreamRead()">
 <h3>resetHasSwitchedToStreamRead</h3>
 <div class="member-signature"><span class="annotations">@LimitedPrivate("Unittest")
-</span><span class="modifiers">static final</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1326">resetHasSwitchedToStreamRead</a></span>()</div>
+</span><span class="modifiers">static final</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html#line-1324">resetHasSwitchedToStreamRead</a></span>()</div>
 </section>
 </li>
 </ul>
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html b/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html
index 4bcf5fa6220..3c845fd720d 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/StoreScanner.html
@@ -977,370 +977,368 @@
 <span class="source-line-no">964</span><span id="line-964">    } while ((nextCell = this.heap.peek()) != null &amp;&amp; CellUtil.matchingRowColumn(cell, nextCell));</span>
 <span class="source-line-no">965</span><span id="line-965">    // We need this check because it may happen that the new scanner that we get</span>
 <span class="source-line-no">966</span><span id="line-966">    // during heap.next() is requiring reseek due of fake KV previously generated for</span>
-<span class="source-line-no">967</span><span id="line-967">    // ROWCOL bloom filter optimization. See HBASE-19863 for more details</span>
-<span class="source-line-no">968</span><span id="line-968">    if (</span>
-<span class="source-line-no">969</span><span id="line-969">      useRowColBloom &amp;&amp; nextCell != null &amp;&amp; cell.getTimestamp() == PrivateConstants.OLDEST_TIMESTAMP</span>
-<span class="source-line-no">970</span><span id="line-970">    ) {</span>
-<span class="source-line-no">971</span><span id="line-971">      return false;</span>
-<span class="source-line-no">972</span><span id="line-972">    }</span>
-<span class="source-line-no">973</span><span id="line-973">    return true;</span>
-<span class="source-line-no">974</span><span id="line-974">  }</span>
-<span class="source-line-no">975</span><span id="line-975"></span>
-<span class="source-line-no">976</span><span id="line-976">  @Override</span>
-<span class="source-line-no">977</span><span id="line-977">  public long getReadPoint() {</span>
-<span class="source-line-no">978</span><span id="line-978">    return this.readPt;</span>
-<span class="source-line-no">979</span><span id="line-979">  }</span>
-<span class="source-line-no">980</span><span id="line-980"></span>
-<span class="source-line-no">981</span><span id="line-981">  private static void clearAndClose(List&lt;KeyValueScanner&gt; scanners) {</span>
-<span class="source-line-no">982</span><span id="line-982">    if (scanners == null) {</span>
-<span class="source-line-no">983</span><span id="line-983">      return;</span>
-<span class="source-line-no">984</span><span id="line-984">    }</span>
-<span class="source-line-no">985</span><span id="line-985">    for (KeyValueScanner s : scanners) {</span>
-<span class="source-line-no">986</span><span id="line-986">      s.close();</span>
-<span class="source-line-no">987</span><span id="line-987">    }</span>
-<span class="source-line-no">988</span><span id="line-988">    scanners.clear();</span>
-<span class="source-line-no">989</span><span id="line-989">  }</span>
-<span class="source-line-no">990</span><span id="line-990"></span>
-<span class="source-line-no">991</span><span id="line-991">  // Implementation of ChangedReadersObserver</span>
-<span class="source-line-no">992</span><span id="line-992">  @Override</span>
-<span class="source-line-no">993</span><span id="line-993">  public void updateReaders(List&lt;HStoreFile&gt; sfs, List&lt;KeyValueScanner&gt; memStoreScanners)</span>
-<span class="source-line-no">994</span><span id="line-994">    throws IOException {</span>
-<span class="source-line-no">995</span><span id="line-995">    if (CollectionUtils.isEmpty(sfs) &amp;&amp; CollectionUtils.isEmpty(memStoreScanners)) {</span>
-<span class="source-line-no">996</span><span id="line-996">      return;</span>
-<span class="source-line-no">997</span><span id="line-997">    }</span>
-<span class="source-line-no">998</span><span id="line-998">    boolean updateReaders = false;</span>
-<span class="source-line-no">999</span><span id="line-999">    flushLock.lock();</span>
-<span class="source-line-no">1000</span><span id="line-1000">    try {</span>
-<span class="source-line-no">1001</span><span id="line-1001">      if (!closeLock.tryLock()) {</span>
-<span class="source-line-no">1002</span><span id="line-1002">        // The reason for doing this is that when the current store scanner does not retrieve</span>
-<span class="source-line-no">1003</span><span id="line-1003">        // any new cells, then the scanner is considered to be done. The heap of this scanner</span>
-<span class="source-line-no">1004</span><span id="line-1004">        // is not closed till the shipped() call is completed. Hence in that case if at all</span>
-<span class="source-line-no">1005</span><span id="line-1005">        // the partial close (close (false)) has been called before updateReaders(), there is no</span>
-<span class="source-line-no">1006</span><span id="line-1006">        // need for the updateReaders() to happen.</span>
-<span class="source-line-no">1007</span><span id="line-1007">        LOG.debug("StoreScanner already has the close lock. There is no need to updateReaders");</span>
-<span class="source-line-no">1008</span><span id="line-1008">        // no lock acquired.</span>
-<span class="source-line-no">1009</span><span id="line-1009">        clearAndClose(memStoreScanners);</span>
-<span class="source-line-no">1010</span><span id="line-1010">        return;</span>
-<span class="source-line-no">1011</span><span id="line-1011">      }</span>
-<span class="source-line-no">1012</span><span id="line-1012">      // lock acquired</span>
-<span class="source-line-no">1013</span><span id="line-1013">      updateReaders = true;</span>
-<span class="source-line-no">1014</span><span id="line-1014">      if (this.closing) {</span>
-<span class="source-line-no">1015</span><span id="line-1015">        LOG.debug("StoreScanner already closing. There is no need to updateReaders");</span>
-<span class="source-line-no">1016</span><span id="line-1016">        clearAndClose(memStoreScanners);</span>
-<span class="source-line-no">1017</span><span id="line-1017">        return;</span>
-<span class="source-line-no">1018</span><span id="line-1018">      }</span>
-<span class="source-line-no">1019</span><span id="line-1019">      flushed = true;</span>
-<span class="source-line-no">1020</span><span id="line-1020">      final boolean isCompaction = false;</span>
-<span class="source-line-no">1021</span><span id="line-1021">      boolean usePread = get || scanUsePread;</span>
-<span class="source-line-no">1022</span><span id="line-1022">      // SEE HBASE-19468 where the flushed files are getting compacted even before a scanner</span>
-<span class="source-line-no">1023</span><span id="line-1023">      // calls next(). So its better we create scanners here rather than next() call. Ensure</span>
-<span class="source-line-no">1024</span><span id="line-1024">      // these scanners are properly closed() whether or not the scan is completed successfully</span>
-<span class="source-line-no">1025</span><span id="line-1025">      // Eagerly creating scanners so that we have the ref counting ticking on the newly created</span>
-<span class="source-line-no">1026</span><span id="line-1026">      // store files. In case of stream scanners this eager creation does not induce performance</span>
-<span class="source-line-no">1027</span><span id="line-1027">      // penalty because in scans (that uses stream scanners) the next() call is bound to happen.</span>
-<span class="source-line-no">1028</span><span id="line-1028">      List&lt;KeyValueScanner&gt; scanners =</span>
-<span class="source-line-no">1029</span><span id="line-1029">        store.getScanners(sfs, cacheBlocks, get, usePread, isCompaction, matcher,</span>
-<span class="source-line-no">1030</span><span id="line-1030">          scan.getStartRow(), scan.getStopRow(), this.readPt, false, isOnlyLatestVersionScan(scan));</span>
-<span class="source-line-no">1031</span><span id="line-1031">      flushedstoreFileScanners.addAll(scanners);</span>
-<span class="source-line-no">1032</span><span id="line-1032">      if (!CollectionUtils.isEmpty(memStoreScanners)) {</span>
-<span class="source-line-no">1033</span><span id="line-1033">        clearAndClose(memStoreScannersAfterFlush);</span>
-<span class="source-line-no">1034</span><span id="line-1034">        memStoreScannersAfterFlush.addAll(memStoreScanners);</span>
-<span class="source-line-no">1035</span><span id="line-1035">      }</span>
-<span class="source-line-no">1036</span><span id="line-1036">    } finally {</span>
-<span class="source-line-no">1037</span><span id="line-1037">      flushLock.unlock();</span>
-<span class="source-line-no">1038</span><span id="line-1038">      if (updateReaders) {</span>
-<span class="source-line-no">1039</span><span id="line-1039">        closeLock.unlock();</span>
-<span class="source-line-no">1040</span><span id="line-1040">      }</span>
-<span class="source-line-no">1041</span><span id="line-1041">      if (hasUpdatedReaders != null) {</span>
-<span class="source-line-no">1042</span><span id="line-1042">        hasUpdatedReaders.set(true);</span>
-<span class="source-line-no">1043</span><span id="line-1043">      }</span>
-<span class="source-line-no">1044</span><span id="line-1044">    }</span>
-<span class="source-line-no">1045</span><span id="line-1045">    // Let the next() call handle re-creating and seeking</span>
-<span class="source-line-no">1046</span><span id="line-1046">  }</span>
-<span class="source-line-no">1047</span><span id="line-1047"></span>
-<span class="source-line-no">1048</span><span id="line-1048">  /** Returns if top of heap has changed (and KeyValueHeap has to try the next KV) */</span>
-<span class="source-line-no">1049</span><span id="line-1049">  protected final boolean reopenAfterFlush() throws IOException {</span>
-<span class="source-line-no">1050</span><span id="line-1050">    // here we can make sure that we have a Store instance so no null check on store.</span>
-<span class="source-line-no">1051</span><span id="line-1051">    ExtendedCell lastTop = heap.peek();</span>
-<span class="source-line-no">1052</span><span id="line-1052">    // When we have the scan object, should we not pass it to getScanners() to get a limited set of</span>
-<span class="source-line-no">1053</span><span id="line-1053">    // scanners? We did so in the constructor and we could have done it now by storing the scan</span>
-<span class="source-line-no">1054</span><span id="line-1054">    // object from the constructor</span>
-<span class="source-line-no">1055</span><span id="line-1055">    List&lt;KeyValueScanner&gt; scanners;</span>
-<span class="source-line-no">1056</span><span id="line-1056">    flushLock.lock();</span>
-<span class="source-line-no">1057</span><span id="line-1057">    try {</span>
-<span class="source-line-no">1058</span><span id="line-1058">      List&lt;KeyValueScanner&gt; allScanners =</span>
-<span class="source-line-no">1059</span><span id="line-1059">        new ArrayList&lt;&gt;(flushedstoreFileScanners.size() + memStoreScannersAfterFlush.size());</span>
-<span class="source-line-no">1060</span><span id="line-1060">      allScanners.addAll(flushedstoreFileScanners);</span>
-<span class="source-line-no">1061</span><span id="line-1061">      allScanners.addAll(memStoreScannersAfterFlush);</span>
-<span class="source-line-no">1062</span><span id="line-1062">      scanners = selectScannersFrom(store, allScanners);</span>
-<span class="source-line-no">1063</span><span id="line-1063">      // Clear the current set of flushed store files scanners so that they don't get added again</span>
-<span class="source-line-no">1064</span><span id="line-1064">      flushedstoreFileScanners.clear();</span>
-<span class="source-line-no">1065</span><span id="line-1065">      memStoreScannersAfterFlush.clear();</span>
-<span class="source-line-no">1066</span><span id="line-1066">    } finally {</span>
-<span class="source-line-no">1067</span><span id="line-1067">      flushLock.unlock();</span>
-<span class="source-line-no">1068</span><span id="line-1068">    }</span>
-<span class="source-line-no">1069</span><span id="line-1069"></span>
-<span class="source-line-no">1070</span><span id="line-1070">    // Seek the new scanners to the last key</span>
-<span class="source-line-no">1071</span><span id="line-1071">    seekScanners(scanners, lastTop, false, parallelSeekEnabled);</span>
-<span class="source-line-no">1072</span><span id="line-1072">    // remove the older memstore scanner</span>
-<span class="source-line-no">1073</span><span id="line-1073">    for (int i = currentScanners.size() - 1; i &gt;= 0; i--) {</span>
-<span class="source-line-no">1074</span><span id="line-1074">      if (!currentScanners.get(i).isFileScanner()) {</span>
-<span class="source-line-no">1075</span><span id="line-1075">        scannersForDelayedClose.add(currentScanners.remove(i));</span>
-<span class="source-line-no">1076</span><span id="line-1076">      } else {</span>
-<span class="source-line-no">1077</span><span id="line-1077">        // we add the memstore scanner to the end of currentScanners</span>
-<span class="source-line-no">1078</span><span id="line-1078">        break;</span>
-<span class="source-line-no">1079</span><span id="line-1079">      }</span>
-<span class="source-line-no">1080</span><span id="line-1080">    }</span>
-<span class="source-line-no">1081</span><span id="line-1081">    // add the newly created scanners on the flushed files and the current active memstore scanner</span>
-<span class="source-line-no">1082</span><span id="line-1082">    addCurrentScanners(scanners);</span>
-<span class="source-line-no">1083</span><span id="line-1083">    // Combine all seeked scanners with a heap</span>
-<span class="source-line-no">1084</span><span id="line-1084">    resetKVHeap(this.currentScanners, store.getComparator());</span>
-<span class="source-line-no">1085</span><span id="line-1085">    resetQueryMatcher(lastTop);</span>
-<span class="source-line-no">1086</span><span id="line-1086">    if (heap.peek() == null || store.getComparator().compareRows(lastTop, this.heap.peek()) != 0) {</span>
-<span class="source-line-no">1087</span><span id="line-1087">      LOG.info("Storescanner.peek() is changed where before = " + lastTop.toString()</span>
-<span class="source-line-no">1088</span><span id="line-1088">        + ",and after = " + heap.peek());</span>
-<span class="source-line-no">1089</span><span id="line-1089">      topChanged = true;</span>
-<span class="source-line-no">1090</span><span id="line-1090">    } else {</span>
-<span class="source-line-no">1091</span><span id="line-1091">      topChanged = false;</span>
-<span class="source-line-no">1092</span><span id="line-1092">    }</span>
-<span class="source-line-no">1093</span><span id="line-1093">    return topChanged;</span>
-<span class="source-line-no">1094</span><span id="line-1094">  }</span>
-<span class="source-line-no">1095</span><span id="line-1095"></span>
-<span class="source-line-no">1096</span><span id="line-1096">  private void resetQueryMatcher(ExtendedCell lastTopKey) {</span>
-<span class="source-line-no">1097</span><span id="line-1097">    // Reset the state of the Query Matcher and set to top row.</span>
-<span class="source-line-no">1098</span><span id="line-1098">    // Only reset and call setRow if the row changes; avoids confusing the</span>
-<span class="source-line-no">1099</span><span id="line-1099">    // query matcher if scanning intra-row.</span>
-<span class="source-line-no">1100</span><span id="line-1100">    ExtendedCell cell = heap.peek();</span>
-<span class="source-line-no">1101</span><span id="line-1101">    if (cell == null) {</span>
-<span class="source-line-no">1102</span><span id="line-1102">      cell = lastTopKey;</span>
-<span class="source-line-no">1103</span><span id="line-1103">    }</span>
-<span class="source-line-no">1104</span><span id="line-1104">    if ((matcher.currentRow() == null) || !CellUtil.matchingRows(cell, matcher.currentRow())) {</span>
-<span class="source-line-no">1105</span><span id="line-1105">      this.countPerRow = 0;</span>
-<span class="source-line-no">1106</span><span id="line-1106">      // The setToNewRow will call reset internally</span>
-<span class="source-line-no">1107</span><span id="line-1107">      matcher.setToNewRow(cell);</span>
-<span class="source-line-no">1108</span><span id="line-1108">    }</span>
-<span class="source-line-no">1109</span><span id="line-1109">  }</span>
-<span class="source-line-no">1110</span><span id="line-1110"></span>
-<span class="source-line-no">1111</span><span id="line-1111">  /**</span>
-<span class="source-line-no">1112</span><span id="line-1112">   * Check whether scan as expected order</span>
-<span class="source-line-no">1113</span><span id="line-1113">   */</span>
-<span class="source-line-no">1114</span><span id="line-1114">  protected void checkScanOrder(Cell prevKV, Cell kv, CellComparator comparator)</span>
-<span class="source-line-no">1115</span><span id="line-1115">    throws IOException {</span>
-<span class="source-line-no">1116</span><span id="line-1116">    // Check that the heap gives us KVs in an increasing order.</span>
-<span class="source-line-no">1117</span><span id="line-1117">    assert prevKV == null || comparator == null || comparator.compare(prevKV, kv) &lt;= 0</span>
-<span class="source-line-no">1118</span><span id="line-1118">      : "Key " + prevKV + " followed by a smaller key " + kv + " in cf " + store;</span>
-<span class="source-line-no">1119</span><span id="line-1119">  }</span>
-<span class="source-line-no">1120</span><span id="line-1120"></span>
-<span class="source-line-no">1121</span><span id="line-1121">  protected boolean seekToNextRow(ExtendedCell c) throws IOException {</span>
-<span class="source-line-no">1122</span><span id="line-1122">    return reseek(PrivateCellUtil.createLastOnRow(c));</span>
-<span class="source-line-no">1123</span><span id="line-1123">  }</span>
-<span class="source-line-no">1124</span><span id="line-1124"></span>
-<span class="source-line-no">1125</span><span id="line-1125">  /**</span>
-<span class="source-line-no">1126</span><span id="line-1126">   * Do a reseek in a normal StoreScanner(scan forward)</span>
-<span class="source-line-no">1127</span><span id="line-1127">   * @return true if scanner has values left, false if end of scanner</span>
-<span class="source-line-no">1128</span><span id="line-1128">   */</span>
-<span class="source-line-no">1129</span><span id="line-1129">  protected boolean seekAsDirection(ExtendedCell kv) throws IOException {</span>
-<span class="source-line-no">1130</span><span id="line-1130">    return reseek(kv);</span>
-<span class="source-line-no">1131</span><span id="line-1131">  }</span>
-<span class="source-line-no">1132</span><span id="line-1132"></span>
-<span class="source-line-no">1133</span><span id="line-1133">  @Override</span>
-<span class="source-line-no">1134</span><span id="line-1134">  public boolean reseek(ExtendedCell kv) throws IOException {</span>
-<span class="source-line-no">1135</span><span id="line-1135">    if (checkFlushed()) {</span>
-<span class="source-line-no">1136</span><span id="line-1136">      reopenAfterFlush();</span>
-<span class="source-line-no">1137</span><span id="line-1137">    }</span>
-<span class="source-line-no">1138</span><span id="line-1138">    if (explicitColumnQuery &amp;&amp; lazySeekEnabledGlobally) {</span>
-<span class="source-line-no">1139</span><span id="line-1139">      return heap.requestSeek(kv, true, useRowColBloom);</span>
-<span class="source-line-no">1140</span><span id="line-1140">    }</span>
-<span class="source-line-no">1141</span><span id="line-1141">    return heap.reseek(kv);</span>
-<span class="source-line-no">1142</span><span id="line-1142">  }</span>
-<span class="source-line-no">1143</span><span id="line-1143"></span>
-<span class="source-line-no">1144</span><span id="line-1144">  void trySwitchToStreamRead() {</span>
-<span class="source-line-no">1145</span><span id="line-1145">    if (</span>
-<span class="source-line-no">1146</span><span id="line-1146">      readType != Scan.ReadType.DEFAULT || !scanUsePread || closing || heap.peek() == null</span>
-<span class="source-line-no">1147</span><span id="line-1147">        || bytesRead &lt; preadMaxBytes</span>
-<span class="source-line-no">1148</span><span id="line-1148">    ) {</span>
-<span class="source-line-no">1149</span><span id="line-1149">      return;</span>
-<span class="source-line-no">1150</span><span id="line-1150">    }</span>
-<span class="source-line-no">1151</span><span id="line-1151">    LOG.debug("Switch to stream read (scanned={} bytes) of {}", bytesRead,</span>
-<span class="source-line-no">1152</span><span id="line-1152">      this.store.getColumnFamilyName());</span>
-<span class="source-line-no">1153</span><span id="line-1153">    scanUsePread = false;</span>
-<span class="source-line-no">1154</span><span id="line-1154">    ExtendedCell lastTop = heap.peek();</span>
-<span class="source-line-no">1155</span><span id="line-1155">    List&lt;KeyValueScanner&gt; memstoreScanners = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">1156</span><span id="line-1156">    List&lt;KeyValueScanner&gt; scannersToClose = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">1157</span><span id="line-1157">    for (KeyValueScanner kvs : currentScanners) {</span>
-<span class="source-line-no">1158</span><span id="line-1158">      if (!kvs.isFileScanner()) {</span>
-<span class="source-line-no">1159</span><span id="line-1159">        // collect memstorescanners here</span>
-<span class="source-line-no">1160</span><span id="line-1160">        memstoreScanners.add(kvs);</span>
-<span class="source-line-no">1161</span><span id="line-1161">      } else {</span>
-<span class="source-line-no">1162</span><span id="line-1162">        scannersToClose.add(kvs);</span>
-<span class="source-line-no">1163</span><span id="line-1163">      }</span>
-<span class="source-line-no">1164</span><span id="line-1164">    }</span>
-<span class="source-line-no">1165</span><span id="line-1165">    List&lt;KeyValueScanner&gt; fileScanners = null;</span>
-<span class="source-line-no">1166</span><span id="line-1166">    List&lt;KeyValueScanner&gt; newCurrentScanners;</span>
-<span class="source-line-no">1167</span><span id="line-1167">    KeyValueHeap newHeap;</span>
-<span class="source-line-no">1168</span><span id="line-1168">    try {</span>
-<span class="source-line-no">1169</span><span id="line-1169">      // We must have a store instance here so no null check</span>
-<span class="source-line-no">1170</span><span id="line-1170">      // recreate the scanners on the current file scanners</span>
-<span class="source-line-no">1171</span><span id="line-1171">      fileScanners = store.recreateScanners(scannersToClose, cacheBlocks, false, false, matcher,</span>
-<span class="source-line-no">1172</span><span id="line-1172">        scan.getStartRow(), scan.includeStartRow(), scan.getStopRow(), scan.includeStopRow(),</span>
-<span class="source-line-no">1173</span><span id="line-1173">        readPt, false);</span>
-<span class="source-line-no">1174</span><span id="line-1174">      if (fileScanners == null) {</span>
-<span class="source-line-no">1175</span><span id="line-1175">        return;</span>
-<span class="source-line-no">1176</span><span id="line-1176">      }</span>
-<span class="source-line-no">1177</span><span id="line-1177">      seekScanners(fileScanners, lastTop, false, parallelSeekEnabled);</span>
-<span class="source-line-no">1178</span><span id="line-1178">      newCurrentScanners = new ArrayList&lt;&gt;(fileScanners.size() + memstoreScanners.size());</span>
-<span class="source-line-no">1179</span><span id="line-1179">      newCurrentScanners.addAll(fileScanners);</span>
-<span class="source-line-no">1180</span><span id="line-1180">      newCurrentScanners.addAll(memstoreScanners);</span>
-<span class="source-line-no">1181</span><span id="line-1181">      newHeap = newKVHeap(newCurrentScanners, comparator);</span>
-<span class="source-line-no">1182</span><span id="line-1182">    } catch (Exception e) {</span>
-<span class="source-line-no">1183</span><span id="line-1183">      LOG.warn("failed to switch to stream read", e);</span>
-<span class="source-line-no">1184</span><span id="line-1184">      if (fileScanners != null) {</span>
-<span class="source-line-no">1185</span><span id="line-1185">        fileScanners.forEach(KeyValueScanner::close);</span>
-<span class="source-line-no">1186</span><span id="line-1186">      }</span>
-<span class="source-line-no">1187</span><span id="line-1187">      return;</span>
-<span class="source-line-no">1188</span><span id="line-1188">    }</span>
-<span class="source-line-no">1189</span><span id="line-1189">    currentScanners.clear();</span>
-<span class="source-line-no">1190</span><span id="line-1190">    addCurrentScanners(newCurrentScanners);</span>
-<span class="source-line-no">1191</span><span id="line-1191">    this.heap = newHeap;</span>
-<span class="source-line-no">1192</span><span id="line-1192">    resetQueryMatcher(lastTop);</span>
-<span class="source-line-no">1193</span><span id="line-1193">    scannersToClose.forEach(KeyValueScanner::close);</span>
-<span class="source-line-no">1194</span><span id="line-1194">    if (hasSwitchedToStreamRead != null) {</span>
-<span class="source-line-no">1195</span><span id="line-1195">      hasSwitchedToStreamRead.set(true);</span>
-<span class="source-line-no">1196</span><span id="line-1196">    }</span>
-<span class="source-line-no">1197</span><span id="line-1197">  }</span>
-<span class="source-line-no">1198</span><span id="line-1198"></span>
-<span class="source-line-no">1199</span><span id="line-1199">  protected final boolean checkFlushed() {</span>
-<span class="source-line-no">1200</span><span id="line-1200">    // check the var without any lock. Suppose even if we see the old</span>
-<span class="source-line-no">1201</span><span id="line-1201">    // value here still it is ok to continue because we will not be resetting</span>
-<span class="source-line-no">1202</span><span id="line-1202">    // the heap but will continue with the referenced memstore's snapshot. For compactions</span>
-<span class="source-line-no">1203</span><span id="line-1203">    // any way we don't need the updateReaders at all to happen as we still continue with</span>
-<span class="source-line-no">1204</span><span id="line-1204">    // the older files</span>
-<span class="source-line-no">1205</span><span id="line-1205">    if (flushed) {</span>
-<span class="source-line-no">1206</span><span id="line-1206">      // If there is a flush and the current scan is notified on the flush ensure that the</span>
-<span class="source-line-no">1207</span><span id="line-1207">      // scan's heap gets reset and we do a seek on the newly flushed file.</span>
-<span class="source-line-no">1208</span><span id="line-1208">      if (this.closing) {</span>
-<span class="source-line-no">1209</span><span id="line-1209">        return false;</span>
-<span class="source-line-no">1210</span><span id="line-1210">      }</span>
-<span class="source-line-no">1211</span><span id="line-1211">      // reset the flag</span>
-<span class="source-line-no">1212</span><span id="line-1212">      flushed = false;</span>
-<span class="source-line-no">1213</span><span id="line-1213">      return true;</span>
-<span class="source-line-no">1214</span><span id="line-1214">    }</span>
-<span class="source-line-no">1215</span><span id="line-1215">    return false;</span>
-<span class="source-line-no">1216</span><span id="line-1216">  }</span>
-<span class="source-line-no">1217</span><span id="line-1217"></span>
-<span class="source-line-no">1218</span><span id="line-1218">  /**</span>
-<span class="source-line-no">1219</span><span id="line-1219">   * Seek storefiles in parallel to optimize IO latency as much as possible</span>
-<span class="source-line-no">1220</span><span id="line-1220">   * @param scanners the list {@link KeyValueScanner}s to be read from</span>
-<span class="source-line-no">1221</span><span id="line-1221">   * @param kv       the KeyValue on which the operation is being requested</span>
-<span class="source-line-no">1222</span><span id="line-1222">   */</span>
-<span class="source-line-no">1223</span><span id="line-1223">  private void parallelSeek(final List&lt;? extends KeyValueScanner&gt; scanners, final ExtendedCell kv)</span>
-<span class="source-line-no">1224</span><span id="line-1224">    throws IOException {</span>
-<span class="source-line-no">1225</span><span id="line-1225">    if (scanners.isEmpty()) return;</span>
-<span class="source-line-no">1226</span><span id="line-1226">    int storeFileScannerCount = scanners.size();</span>
-<span class="source-line-no">1227</span><span id="line-1227">    CountDownLatch latch = new CountDownLatch(storeFileScannerCount);</span>
-<span class="source-line-no">1228</span><span id="line-1228">    List&lt;ParallelSeekHandler&gt; handlers = new ArrayList&lt;&gt;(storeFileScannerCount);</span>
-<span class="source-line-no">1229</span><span id="line-1229">    for (KeyValueScanner scanner : scanners) {</span>
-<span class="source-line-no">1230</span><span id="line-1230">      if (scanner instanceof StoreFileScanner) {</span>
-<span class="source-line-no">1231</span><span id="line-1231">        ParallelSeekHandler seekHandler = new ParallelSeekHandler(scanner, kv, this.readPt, latch);</span>
-<span class="source-line-no">1232</span><span id="line-1232">        executor.submit(seekHandler);</span>
-<span class="source-line-no">1233</span><span id="line-1233">        handlers.add(seekHandler);</span>
-<span class="source-line-no">1234</span><span id="line-1234">      } else {</span>
-<span class="source-line-no">1235</span><span id="line-1235">        scanner.seek(kv);</span>
-<span class="source-line-no">1236</span><span id="line-1236">        latch.countDown();</span>
-<span class="source-line-no">1237</span><span id="line-1237">      }</span>
-<span class="source-line-no">1238</span><span id="line-1238">    }</span>
-<span class="source-line-no">1239</span><span id="line-1239"></span>
-<span class="source-line-no">1240</span><span id="line-1240">    try {</span>
-<span class="source-line-no">1241</span><span id="line-1241">      latch.await();</span>
-<span class="source-line-no">1242</span><span id="line-1242">    } catch (InterruptedException ie) {</span>
-<span class="source-line-no">1243</span><span id="line-1243">      throw (InterruptedIOException) new InterruptedIOException().initCause(ie);</span>
-<span class="source-line-no">1244</span><span id="line-1244">    }</span>
-<span class="source-line-no">1245</span><span id="line-1245"></span>
-<span class="source-line-no">1246</span><span id="line-1246">    for (ParallelSeekHandler handler : handlers) {</span>
-<span class="source-line-no">1247</span><span id="line-1247">      if (handler.getErr() != null) {</span>
-<span class="source-line-no">1248</span><span id="line-1248">        throw new IOException(handler.getErr());</span>
-<span class="source-line-no">1249</span><span id="line-1249">      }</span>
-<span class="source-line-no">1250</span><span id="line-1250">    }</span>
-<span class="source-line-no">1251</span><span id="line-1251">  }</span>
-<span class="source-line-no">1252</span><span id="line-1252"></span>
-<span class="source-line-no">1253</span><span id="line-1253">  /**</span>
-<span class="source-line-no">1254</span><span id="line-1254">   * Used in testing.</span>
-<span class="source-line-no">1255</span><span id="line-1255">   * @return all scanners in no particular order</span>
-<span class="source-line-no">1256</span><span id="line-1256">   */</span>
-<span class="source-line-no">1257</span><span id="line-1257">  List&lt;KeyValueScanner&gt; getAllScannersForTesting() {</span>
-<span class="source-line-no">1258</span><span id="line-1258">    List&lt;KeyValueScanner&gt; allScanners = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">1259</span><span id="line-1259">    KeyValueScanner current = heap.getCurrentForTesting();</span>
-<span class="source-line-no">1260</span><span id="line-1260">    if (current != null) allScanners.add(current);</span>
-<span class="source-line-no">1261</span><span id="line-1261">    for (KeyValueScanner scanner : heap.getHeap())</span>
-<span class="source-line-no">1262</span><span id="line-1262">      allScanners.add(scanner);</span>
-<span class="source-line-no">1263</span><span id="line-1263">    return allScanners;</span>
-<span class="source-line-no">1264</span><span id="line-1264">  }</span>
-<span class="source-line-no">1265</span><span id="line-1265"></span>
-<span class="source-line-no">1266</span><span id="line-1266">  static void enableLazySeekGlobally(boolean enable) {</span>
-<span class="source-line-no">1267</span><span id="line-1267">    lazySeekEnabledGlobally = enable;</span>
-<span class="source-line-no">1268</span><span id="line-1268">  }</span>
-<span class="source-line-no">1269</span><span id="line-1269"></span>
-<span class="source-line-no">1270</span><span id="line-1270">  /** Returns The estimated number of KVs seen by this scanner (includes some skipped KVs). */</span>
-<span class="source-line-no">1271</span><span id="line-1271">  public long getEstimatedNumberOfKvsScanned() {</span>
-<span class="source-line-no">1272</span><span id="line-1272">    return this.kvsScanned;</span>
-<span class="source-line-no">1273</span><span id="line-1273">  }</span>
-<span class="source-line-no">1274</span><span id="line-1274"></span>
-<span class="source-line-no">1275</span><span id="line-1275">  @Override</span>
-<span class="source-line-no">1276</span><span id="line-1276">  public ExtendedCell getNextIndexedKey() {</span>
-<span class="source-line-no">1277</span><span id="line-1277">    return this.heap.getNextIndexedKey();</span>
-<span class="source-line-no">1278</span><span id="line-1278">  }</span>
-<span class="source-line-no">1279</span><span id="line-1279"></span>
-<span class="source-line-no">1280</span><span id="line-1280">  @Override</span>
-<span class="source-line-no">1281</span><span id="line-1281">  public void shipped() throws IOException {</span>
-<span class="source-line-no">1282</span><span id="line-1282">    if (prevCell != null) {</span>
-<span class="source-line-no">1283</span><span id="line-1283">      // Do the copy here so that in case the prevCell ref is pointing to the previous</span>
-<span class="source-line-no">1284</span><span id="line-1284">      // blocks we can safely release those blocks.</span>
-<span class="source-line-no">1285</span><span id="line-1285">      // This applies to blocks that are got from Bucket cache, L1 cache and the blocks</span>
-<span class="source-line-no">1286</span><span id="line-1286">      // fetched from HDFS. Copying this would ensure that we let go the references to these</span>
-<span class="source-line-no">1287</span><span id="line-1287">      // blocks so that they can be GCed safely(in case of bucket cache)</span>
-<span class="source-line-no">1288</span><span id="line-1288">      prevCell = KeyValueUtil.toNewKeyCell(this.prevCell);</span>
-<span class="source-line-no">1289</span><span id="line-1289">    }</span>
-<span class="source-line-no">1290</span><span id="line-1290">    matcher.beforeShipped();</span>
-<span class="source-line-no">1291</span><span id="line-1291">    // There wont be further fetch of Cells from these scanners. Just close.</span>
-<span class="source-line-no">1292</span><span id="line-1292">    clearAndClose(scannersForDelayedClose);</span>
-<span class="source-line-no">1293</span><span id="line-1293">    if (this.heap != null) {</span>
-<span class="source-line-no">1294</span><span id="line-1294">      this.heap.shipped();</span>
-<span class="source-line-no">1295</span><span id="line-1295">      // When switching from pread to stream, we will open a new scanner for each store file, but</span>
-<span class="source-line-no">1296</span><span id="line-1296">      // the old scanner may still track the HFileBlocks we have scanned but not sent back to client</span>
-<span class="source-line-no">1297</span><span id="line-1297">      // yet. If we close the scanner immediately then the HFileBlocks may be messed up by others</span>
-<span class="source-line-no">1298</span><span id="line-1298">      // before we serialize and send it back to client. The HFileBlocks will be released in shipped</span>
-<span class="source-line-no">1299</span><span id="line-1299">      // method, so we here will also open new scanners and close old scanners in shipped method.</span>
-<span class="source-line-no">1300</span><span id="line-1300">      // See HBASE-18055 for more details.</span>
-<span class="source-line-no">1301</span><span id="line-1301">      trySwitchToStreamRead();</span>
-<span class="source-line-no">1302</span><span id="line-1302">    }</span>
-<span class="source-line-no">1303</span><span id="line-1303">  }</span>
-<span class="source-line-no">1304</span><span id="line-1304"></span>
-<span class="source-line-no">1305</span><span id="line-1305">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
-<span class="source-line-no">1306</span><span id="line-1306">  static final void instrument() {</span>
-<span class="source-line-no">1307</span><span id="line-1307">    hasUpdatedReaders = new AtomicBoolean(false);</span>
-<span class="source-line-no">1308</span><span id="line-1308">    hasSwitchedToStreamRead = new AtomicBoolean(false);</span>
-<span class="source-line-no">1309</span><span id="line-1309">  }</span>
-<span class="source-line-no">1310</span><span id="line-1310"></span>
-<span class="source-line-no">1311</span><span id="line-1311">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
-<span class="source-line-no">1312</span><span id="line-1312">  static final boolean hasUpdatedReaders() {</span>
-<span class="source-line-no">1313</span><span id="line-1313">    return hasUpdatedReaders.get();</span>
-<span class="source-line-no">1314</span><span id="line-1314">  }</span>
-<span class="source-line-no">1315</span><span id="line-1315"></span>
-<span class="source-line-no">1316</span><span id="line-1316">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
-<span class="source-line-no">1317</span><span id="line-1317">  static final boolean hasSwitchedToStreamRead() {</span>
-<span class="source-line-no">1318</span><span id="line-1318">    return hasSwitchedToStreamRead.get();</span>
-<span class="source-line-no">1319</span><span id="line-1319">  }</span>
-<span class="source-line-no">1320</span><span id="line-1320"></span>
-<span class="source-line-no">1321</span><span id="line-1321">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
-<span class="source-line-no">1322</span><span id="line-1322">  static final void resetHasUpdatedReaders() {</span>
-<span class="source-line-no">1323</span><span id="line-1323">    hasUpdatedReaders.set(false);</span>
-<span class="source-line-no">1324</span><span id="line-1324">  }</span>
-<span class="source-line-no">1325</span><span id="line-1325"></span>
-<span class="source-line-no">1326</span><span id="line-1326">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
-<span class="source-line-no">1327</span><span id="line-1327">  static final void resetHasSwitchedToStreamRead() {</span>
-<span class="source-line-no">1328</span><span id="line-1328">    hasSwitchedToStreamRead.set(false);</span>
-<span class="source-line-no">1329</span><span id="line-1329">  }</span>
-<span class="source-line-no">1330</span><span id="line-1330">}</span>
+<span class="source-line-no">967</span><span id="line-967">    // ROWCOL bloom filter optimization. See HBASE-19863 and HBASE-29907 for more details</span>
+<span class="source-line-no">968</span><span id="line-968">    if (useRowColBloom &amp;&amp; nextCell != null &amp;&amp; matcher.compareKeyForNextColumn(nextCell, cell) &lt; 0) {</span>
+<span class="source-line-no">969</span><span id="line-969">      return false;</span>
+<span class="source-line-no">970</span><span id="line-970">    }</span>
+<span class="source-line-no">971</span><span id="line-971">    return true;</span>
+<span class="source-line-no">972</span><span id="line-972">  }</span>
+<span class="source-line-no">973</span><span id="line-973"></span>
+<span class="source-line-no">974</span><span id="line-974">  @Override</span>
+<span class="source-line-no">975</span><span id="line-975">  public long getReadPoint() {</span>
+<span class="source-line-no">976</span><span id="line-976">    return this.readPt;</span>
+<span class="source-line-no">977</span><span id="line-977">  }</span>
+<span class="source-line-no">978</span><span id="line-978"></span>
+<span class="source-line-no">979</span><span id="line-979">  private static void clearAndClose(List&lt;KeyValueScanner&gt; scanners) {</span>
+<span class="source-line-no">980</span><span id="line-980">    if (scanners == null) {</span>
+<span class="source-line-no">981</span><span id="line-981">      return;</span>
+<span class="source-line-no">982</span><span id="line-982">    }</span>
+<span class="source-line-no">983</span><span id="line-983">    for (KeyValueScanner s : scanners) {</span>
+<span class="source-line-no">984</span><span id="line-984">      s.close();</span>
+<span class="source-line-no">985</span><span id="line-985">    }</span>
+<span class="source-line-no">986</span><span id="line-986">    scanners.clear();</span>
+<span class="source-line-no">987</span><span id="line-987">  }</span>
+<span class="source-line-no">988</span><span id="line-988"></span>
+<span class="source-line-no">989</span><span id="line-989">  // Implementation of ChangedReadersObserver</span>
+<span class="source-line-no">990</span><span id="line-990">  @Override</span>
+<span class="source-line-no">991</span><span id="line-991">  public void updateReaders(List&lt;HStoreFile&gt; sfs, List&lt;KeyValueScanner&gt; memStoreScanners)</span>
+<span class="source-line-no">992</span><span id="line-992">    throws IOException {</span>
+<span class="source-line-no">993</span><span id="line-993">    if (CollectionUtils.isEmpty(sfs) &amp;&amp; CollectionUtils.isEmpty(memStoreScanners)) {</span>
+<span class="source-line-no">994</span><span id="line-994">      return;</span>
+<span class="source-line-no">995</span><span id="line-995">    }</span>
+<span class="source-line-no">996</span><span id="line-996">    boolean updateReaders = false;</span>
+<span class="source-line-no">997</span><span id="line-997">    flushLock.lock();</span>
+<span class="source-line-no">998</span><span id="line-998">    try {</span>
+<span class="source-line-no">999</span><span id="line-999">      if (!closeLock.tryLock()) {</span>
+<span class="source-line-no">1000</span><span id="line-1000">        // The reason for doing this is that when the current store scanner does not retrieve</span>
+<span class="source-line-no">1001</span><span id="line-1001">        // any new cells, then the scanner is considered to be done. The heap of this scanner</span>
+<span class="source-line-no">1002</span><span id="line-1002">        // is not closed till the shipped() call is completed. Hence in that case if at all</span>
+<span class="source-line-no">1003</span><span id="line-1003">        // the partial close (close (false)) has been called before updateReaders(), there is no</span>
+<span class="source-line-no">1004</span><span id="line-1004">        // need for the updateReaders() to happen.</span>
+<span class="source-line-no">1005</span><span id="line-1005">        LOG.debug("StoreScanner already has the close lock. There is no need to updateReaders");</span>
+<span class="source-line-no">1006</span><span id="line-1006">        // no lock acquired.</span>
+<span class="source-line-no">1007</span><span id="line-1007">        clearAndClose(memStoreScanners);</span>
+<span class="source-line-no">1008</span><span id="line-1008">        return;</span>
+<span class="source-line-no">1009</span><span id="line-1009">      }</span>
+<span class="source-line-no">1010</span><span id="line-1010">      // lock acquired</span>
+<span class="source-line-no">1011</span><span id="line-1011">      updateReaders = true;</span>
+<span class="source-line-no">1012</span><span id="line-1012">      if (this.closing) {</span>
+<span class="source-line-no">1013</span><span id="line-1013">        LOG.debug("StoreScanner already closing. There is no need to updateReaders");</span>
+<span class="source-line-no">1014</span><span id="line-1014">        clearAndClose(memStoreScanners);</span>
+<span class="source-line-no">1015</span><span id="line-1015">        return;</span>
+<span class="source-line-no">1016</span><span id="line-1016">      }</span>
+<span class="source-line-no">1017</span><span id="line-1017">      flushed = true;</span>
+<span class="source-line-no">1018</span><span id="line-1018">      final boolean isCompaction = false;</span>
+<span class="source-line-no">1019</span><span id="line-1019">      boolean usePread = get || scanUsePread;</span>
+<span class="source-line-no">1020</span><span id="line-1020">      // SEE HBASE-19468 where the flushed files are getting compacted even before a scanner</span>
+<span class="source-line-no">1021</span><span id="line-1021">      // calls next(). So its better we create scanners here rather than next() call. Ensure</span>
+<span class="source-line-no">1022</span><span id="line-1022">      // these scanners are properly closed() whether or not the scan is completed successfully</span>
+<span class="source-line-no">1023</span><span id="line-1023">      // Eagerly creating scanners so that we have the ref counting ticking on the newly created</span>
+<span class="source-line-no">1024</span><span id="line-1024">      // store files. In case of stream scanners this eager creation does not induce performance</span>
+<span class="source-line-no">1025</span><span id="line-1025">      // penalty because in scans (that uses stream scanners) the next() call is bound to happen.</span>
+<span class="source-line-no">1026</span><span id="line-1026">      List&lt;KeyValueScanner&gt; scanners =</span>
+<span class="source-line-no">1027</span><span id="line-1027">        store.getScanners(sfs, cacheBlocks, get, usePread, isCompaction, matcher,</span>
+<span class="source-line-no">1028</span><span id="line-1028">          scan.getStartRow(), scan.getStopRow(), this.readPt, false, isOnlyLatestVersionScan(scan));</span>
+<span class="source-line-no">1029</span><span id="line-1029">      flushedstoreFileScanners.addAll(scanners);</span>
+<span class="source-line-no">1030</span><span id="line-1030">      if (!CollectionUtils.isEmpty(memStoreScanners)) {</span>
+<span class="source-line-no">1031</span><span id="line-1031">        clearAndClose(memStoreScannersAfterFlush);</span>
+<span class="source-line-no">1032</span><span id="line-1032">        memStoreScannersAfterFlush.addAll(memStoreScanners);</span>
+<span class="source-line-no">1033</span><span id="line-1033">      }</span>
+<span class="source-line-no">1034</span><span id="line-1034">    } finally {</span>
+<span class="source-line-no">1035</span><span id="line-1035">      flushLock.unlock();</span>
+<span class="source-line-no">1036</span><span id="line-1036">      if (updateReaders) {</span>
+<span class="source-line-no">1037</span><span id="line-1037">        closeLock.unlock();</span>
+<span class="source-line-no">1038</span><span id="line-1038">      }</span>
+<span class="source-line-no">1039</span><span id="line-1039">      if (hasUpdatedReaders != null) {</span>
+<span class="source-line-no">1040</span><span id="line-1040">        hasUpdatedReaders.set(true);</span>
+<span class="source-line-no">1041</span><span id="line-1041">      }</span>
+<span class="source-line-no">1042</span><span id="line-1042">    }</span>
+<span class="source-line-no">1043</span><span id="line-1043">    // Let the next() call handle re-creating and seeking</span>
+<span class="source-line-no">1044</span><span id="line-1044">  }</span>
+<span class="source-line-no">1045</span><span id="line-1045"></span>
+<span class="source-line-no">1046</span><span id="line-1046">  /** Returns if top of heap has changed (and KeyValueHeap has to try the next KV) */</span>
+<span class="source-line-no">1047</span><span id="line-1047">  protected final boolean reopenAfterFlush() throws IOException {</span>
+<span class="source-line-no">1048</span><span id="line-1048">    // here we can make sure that we have a Store instance so no null check on store.</span>
+<span class="source-line-no">1049</span><span id="line-1049">    ExtendedCell lastTop = heap.peek();</span>
+<span class="source-line-no">1050</span><span id="line-1050">    // When we have the scan object, should we not pass it to getScanners() to get a limited set of</span>
+<span class="source-line-no">1051</span><span id="line-1051">    // scanners? We did so in the constructor and we could have done it now by storing the scan</span>
+<span class="source-line-no">1052</span><span id="line-1052">    // object from the constructor</span>
+<span class="source-line-no">1053</span><span id="line-1053">    List&lt;KeyValueScanner&gt; scanners;</span>
+<span class="source-line-no">1054</span><span id="line-1054">    flushLock.lock();</span>
+<span class="source-line-no">1055</span><span id="line-1055">    try {</span>
+<span class="source-line-no">1056</span><span id="line-1056">      List&lt;KeyValueScanner&gt; allScanners =</span>
+<span class="source-line-no">1057</span><span id="line-1057">        new ArrayList&lt;&gt;(flushedstoreFileScanners.size() + memStoreScannersAfterFlush.size());</span>
+<span class="source-line-no">1058</span><span id="line-1058">      allScanners.addAll(flushedstoreFileScanners);</span>
+<span class="source-line-no">1059</span><span id="line-1059">      allScanners.addAll(memStoreScannersAfterFlush);</span>
+<span class="source-line-no">1060</span><span id="line-1060">      scanners = selectScannersFrom(store, allScanners);</span>
+<span class="source-line-no">1061</span><span id="line-1061">      // Clear the current set of flushed store files scanners so that they don't get added again</span>
+<span class="source-line-no">1062</span><span id="line-1062">      flushedstoreFileScanners.clear();</span>
+<span class="source-line-no">1063</span><span id="line-1063">      memStoreScannersAfterFlush.clear();</span>
+<span class="source-line-no">1064</span><span id="line-1064">    } finally {</span>
+<span class="source-line-no">1065</span><span id="line-1065">      flushLock.unlock();</span>
+<span class="source-line-no">1066</span><span id="line-1066">    }</span>
+<span class="source-line-no">1067</span><span id="line-1067"></span>
+<span class="source-line-no">1068</span><span id="line-1068">    // Seek the new scanners to the last key</span>
+<span class="source-line-no">1069</span><span id="line-1069">    seekScanners(scanners, lastTop, false, parallelSeekEnabled);</span>
+<span class="source-line-no">1070</span><span id="line-1070">    // remove the older memstore scanner</span>
+<span class="source-line-no">1071</span><span id="line-1071">    for (int i = currentScanners.size() - 1; i &gt;= 0; i--) {</span>
+<span class="source-line-no">1072</span><span id="line-1072">      if (!currentScanners.get(i).isFileScanner()) {</span>
+<span class="source-line-no">1073</span><span id="line-1073">        scannersForDelayedClose.add(currentScanners.remove(i));</span>
+<span class="source-line-no">1074</span><span id="line-1074">      } else {</span>
+<span class="source-line-no">1075</span><span id="line-1075">        // we add the memstore scanner to the end of currentScanners</span>
+<span class="source-line-no">1076</span><span id="line-1076">        break;</span>
+<span class="source-line-no">1077</span><span id="line-1077">      }</span>
+<span class="source-line-no">1078</span><span id="line-1078">    }</span>
+<span class="source-line-no">1079</span><span id="line-1079">    // add the newly created scanners on the flushed files and the current active memstore scanner</span>
+<span class="source-line-no">1080</span><span id="line-1080">    addCurrentScanners(scanners);</span>
+<span class="source-line-no">1081</span><span id="line-1081">    // Combine all seeked scanners with a heap</span>
+<span class="source-line-no">1082</span><span id="line-1082">    resetKVHeap(this.currentScanners, store.getComparator());</span>
+<span class="source-line-no">1083</span><span id="line-1083">    resetQueryMatcher(lastTop);</span>
+<span class="source-line-no">1084</span><span id="line-1084">    if (heap.peek() == null || store.getComparator().compareRows(lastTop, this.heap.peek()) != 0) {</span>
+<span class="source-line-no">1085</span><span id="line-1085">      LOG.info("Storescanner.peek() is changed where before = " + lastTop.toString()</span>
+<span class="source-line-no">1086</span><span id="line-1086">        + ",and after = " + heap.peek());</span>
+<span class="source-line-no">1087</span><span id="line-1087">      topChanged = true;</span>
+<span class="source-line-no">1088</span><span id="line-1088">    } else {</span>
+<span class="source-line-no">1089</span><span id="line-1089">      topChanged = false;</span>
+<span class="source-line-no">1090</span><span id="line-1090">    }</span>
+<span class="source-line-no">1091</span><span id="line-1091">    return topChanged;</span>
+<span class="source-line-no">1092</span><span id="line-1092">  }</span>
+<span class="source-line-no">1093</span><span id="line-1093"></span>
+<span class="source-line-no">1094</span><span id="line-1094">  private void resetQueryMatcher(ExtendedCell lastTopKey) {</span>
+<span class="source-line-no">1095</span><span id="line-1095">    // Reset the state of the Query Matcher and set to top row.</span>
+<span class="source-line-no">1096</span><span id="line-1096">    // Only reset and call setRow if the row changes; avoids confusing the</span>
+<span class="source-line-no">1097</span><span id="line-1097">    // query matcher if scanning intra-row.</span>
+<span class="source-line-no">1098</span><span id="line-1098">    ExtendedCell cell = heap.peek();</span>
+<span class="source-line-no">1099</span><span id="line-1099">    if (cell == null) {</span>
+<span class="source-line-no">1100</span><span id="line-1100">      cell = lastTopKey;</span>
+<span class="source-line-no">1101</span><span id="line-1101">    }</span>
+<span class="source-line-no">1102</span><span id="line-1102">    if ((matcher.currentRow() == null) || !CellUtil.matchingRows(cell, matcher.currentRow())) {</span>
+<span class="source-line-no">1103</span><span id="line-1103">      this.countPerRow = 0;</span>
+<span class="source-line-no">1104</span><span id="line-1104">      // The setToNewRow will call reset internally</span>
+<span class="source-line-no">1105</span><span id="line-1105">      matcher.setToNewRow(cell);</span>
+<span class="source-line-no">1106</span><span id="line-1106">    }</span>
+<span class="source-line-no">1107</span><span id="line-1107">  }</span>
+<span class="source-line-no">1108</span><span id="line-1108"></span>
+<span class="source-line-no">1109</span><span id="line-1109">  /**</span>
+<span class="source-line-no">1110</span><span id="line-1110">   * Check whether scan as expected order</span>
+<span class="source-line-no">1111</span><span id="line-1111">   */</span>
+<span class="source-line-no">1112</span><span id="line-1112">  protected void checkScanOrder(Cell prevKV, Cell kv, CellComparator comparator)</span>
+<span class="source-line-no">1113</span><span id="line-1113">    throws IOException {</span>
+<span class="source-line-no">1114</span><span id="line-1114">    // Check that the heap gives us KVs in an increasing order.</span>
+<span class="source-line-no">1115</span><span id="line-1115">    assert prevKV == null || comparator == null || comparator.compare(prevKV, kv) &lt;= 0</span>
+<span class="source-line-no">1116</span><span id="line-1116">      : "Key " + prevKV + " followed by a smaller key " + kv + " in cf " + store;</span>
+<span class="source-line-no">1117</span><span id="line-1117">  }</span>
+<span class="source-line-no">1118</span><span id="line-1118"></span>
+<span class="source-line-no">1119</span><span id="line-1119">  protected boolean seekToNextRow(ExtendedCell c) throws IOException {</span>
+<span class="source-line-no">1120</span><span id="line-1120">    return reseek(PrivateCellUtil.createLastOnRow(c));</span>
+<span class="source-line-no">1121</span><span id="line-1121">  }</span>
+<span class="source-line-no">1122</span><span id="line-1122"></span>
+<span class="source-line-no">1123</span><span id="line-1123">  /**</span>
+<span class="source-line-no">1124</span><span id="line-1124">   * Do a reseek in a normal StoreScanner(scan forward)</span>
+<span class="source-line-no">1125</span><span id="line-1125">   * @return true if scanner has values left, false if end of scanner</span>
+<span class="source-line-no">1126</span><span id="line-1126">   */</span>
+<span class="source-line-no">1127</span><span id="line-1127">  protected boolean seekAsDirection(ExtendedCell kv) throws IOException {</span>
+<span class="source-line-no">1128</span><span id="line-1128">    return reseek(kv);</span>
+<span class="source-line-no">1129</span><span id="line-1129">  }</span>
+<span class="source-line-no">1130</span><span id="line-1130"></span>
+<span class="source-line-no">1131</span><span id="line-1131">  @Override</span>
+<span class="source-line-no">1132</span><span id="line-1132">  public boolean reseek(ExtendedCell kv) throws IOException {</span>
+<span class="source-line-no">1133</span><span id="line-1133">    if (checkFlushed()) {</span>
+<span class="source-line-no">1134</span><span id="line-1134">      reopenAfterFlush();</span>
+<span class="source-line-no">1135</span><span id="line-1135">    }</span>
+<span class="source-line-no">1136</span><span id="line-1136">    if (explicitColumnQuery &amp;&amp; lazySeekEnabledGlobally) {</span>
+<span class="source-line-no">1137</span><span id="line-1137">      return heap.requestSeek(kv, true, useRowColBloom);</span>
+<span class="source-line-no">1138</span><span id="line-1138">    }</span>
+<span class="source-line-no">1139</span><span id="line-1139">    return heap.reseek(kv);</span>
+<span class="source-line-no">1140</span><span id="line-1140">  }</span>
+<span class="source-line-no">1141</span><span id="line-1141"></span>
+<span class="source-line-no">1142</span><span id="line-1142">  void trySwitchToStreamRead() {</span>
+<span class="source-line-no">1143</span><span id="line-1143">    if (</span>
+<span class="source-line-no">1144</span><span id="line-1144">      readType != Scan.ReadType.DEFAULT || !scanUsePread || closing || heap.peek() == null</span>
+<span class="source-line-no">1145</span><span id="line-1145">        || bytesRead &lt; preadMaxBytes</span>
+<span class="source-line-no">1146</span><span id="line-1146">    ) {</span>
+<span class="source-line-no">1147</span><span id="line-1147">      return;</span>
+<span class="source-line-no">1148</span><span id="line-1148">    }</span>
+<span class="source-line-no">1149</span><span id="line-1149">    LOG.debug("Switch to stream read (scanned={} bytes) of {}", bytesRead,</span>
+<span class="source-line-no">1150</span><span id="line-1150">      this.store.getColumnFamilyName());</span>
+<span class="source-line-no">1151</span><span id="line-1151">    scanUsePread = false;</span>
+<span class="source-line-no">1152</span><span id="line-1152">    ExtendedCell lastTop = heap.peek();</span>
+<span class="source-line-no">1153</span><span id="line-1153">    List&lt;KeyValueScanner&gt; memstoreScanners = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">1154</span><span id="line-1154">    List&lt;KeyValueScanner&gt; scannersToClose = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">1155</span><span id="line-1155">    for (KeyValueScanner kvs : currentScanners) {</span>
+<span class="source-line-no">1156</span><span id="line-1156">      if (!kvs.isFileScanner()) {</span>
+<span class="source-line-no">1157</span><span id="line-1157">        // collect memstorescanners here</span>
+<span class="source-line-no">1158</span><span id="line-1158">        memstoreScanners.add(kvs);</span>
+<span class="source-line-no">1159</span><span id="line-1159">      } else {</span>
+<span class="source-line-no">1160</span><span id="line-1160">        scannersToClose.add(kvs);</span>
+<span class="source-line-no">1161</span><span id="line-1161">      }</span>
+<span class="source-line-no">1162</span><span id="line-1162">    }</span>
+<span class="source-line-no">1163</span><span id="line-1163">    List&lt;KeyValueScanner&gt; fileScanners = null;</span>
+<span class="source-line-no">1164</span><span id="line-1164">    List&lt;KeyValueScanner&gt; newCurrentScanners;</span>
+<span class="source-line-no">1165</span><span id="line-1165">    KeyValueHeap newHeap;</span>
+<span class="source-line-no">1166</span><span id="line-1166">    try {</span>
+<span class="source-line-no">1167</span><span id="line-1167">      // We must have a store instance here so no null check</span>
+<span class="source-line-no">1168</span><span id="line-1168">      // recreate the scanners on the current file scanners</span>
+<span class="source-line-no">1169</span><span id="line-1169">      fileScanners = store.recreateScanners(scannersToClose, cacheBlocks, false, false, matcher,</span>
+<span class="source-line-no">1170</span><span id="line-1170">        scan.getStartRow(), scan.includeStartRow(), scan.getStopRow(), scan.includeStopRow(),</span>
+<span class="source-line-no">1171</span><span id="line-1171">        readPt, false);</span>
+<span class="source-line-no">1172</span><span id="line-1172">      if (fileScanners == null) {</span>
+<span class="source-line-no">1173</span><span id="line-1173">        return;</span>
+<span class="source-line-no">1174</span><span id="line-1174">      }</span>
+<span class="source-line-no">1175</span><span id="line-1175">      seekScanners(fileScanners, lastTop, false, parallelSeekEnabled);</span>
+<span class="source-line-no">1176</span><span id="line-1176">      newCurrentScanners = new ArrayList&lt;&gt;(fileScanners.size() + memstoreScanners.size());</span>
+<span class="source-line-no">1177</span><span id="line-1177">      newCurrentScanners.addAll(fileScanners);</span>
+<span class="source-line-no">1178</span><span id="line-1178">      newCurrentScanners.addAll(memstoreScanners);</span>
+<span class="source-line-no">1179</span><span id="line-1179">      newHeap = newKVHeap(newCurrentScanners, comparator);</span>
+<span class="source-line-no">1180</span><span id="line-1180">    } catch (Exception e) {</span>
+<span class="source-line-no">1181</span><span id="line-1181">      LOG.warn("failed to switch to stream read", e);</span>
+<span class="source-line-no">1182</span><span id="line-1182">      if (fileScanners != null) {</span>
+<span class="source-line-no">1183</span><span id="line-1183">        fileScanners.forEach(KeyValueScanner::close);</span>
+<span class="source-line-no">1184</span><span id="line-1184">      }</span>
+<span class="source-line-no">1185</span><span id="line-1185">      return;</span>
+<span class="source-line-no">1186</span><span id="line-1186">    }</span>
+<span class="source-line-no">1187</span><span id="line-1187">    currentScanners.clear();</span>
+<span class="source-line-no">1188</span><span id="line-1188">    addCurrentScanners(newCurrentScanners);</span>
+<span class="source-line-no">1189</span><span id="line-1189">    this.heap = newHeap;</span>
+<span class="source-line-no">1190</span><span id="line-1190">    resetQueryMatcher(lastTop);</span>
+<span class="source-line-no">1191</span><span id="line-1191">    scannersToClose.forEach(KeyValueScanner::close);</span>
+<span class="source-line-no">1192</span><span id="line-1192">    if (hasSwitchedToStreamRead != null) {</span>
+<span class="source-line-no">1193</span><span id="line-1193">      hasSwitchedToStreamRead.set(true);</span>
+<span class="source-line-no">1194</span><span id="line-1194">    }</span>
+<span class="source-line-no">1195</span><span id="line-1195">  }</span>
+<span class="source-line-no">1196</span><span id="line-1196"></span>
+<span class="source-line-no">1197</span><span id="line-1197">  protected final boolean checkFlushed() {</span>
+<span class="source-line-no">1198</span><span id="line-1198">    // check the var without any lock. Suppose even if we see the old</span>
+<span class="source-line-no">1199</span><span id="line-1199">    // value here still it is ok to continue because we will not be resetting</span>
+<span class="source-line-no">1200</span><span id="line-1200">    // the heap but will continue with the referenced memstore's snapshot. For compactions</span>
+<span class="source-line-no">1201</span><span id="line-1201">    // any way we don't need the updateReaders at all to happen as we still continue with</span>
+<span class="source-line-no">1202</span><span id="line-1202">    // the older files</span>
+<span class="source-line-no">1203</span><span id="line-1203">    if (flushed) {</span>
+<span class="source-line-no">1204</span><span id="line-1204">      // If there is a flush and the current scan is notified on the flush ensure that the</span>
+<span class="source-line-no">1205</span><span id="line-1205">      // scan's heap gets reset and we do a seek on the newly flushed file.</span>
+<span class="source-line-no">1206</span><span id="line-1206">      if (this.closing) {</span>
+<span class="source-line-no">1207</span><span id="line-1207">        return false;</span>
+<span class="source-line-no">1208</span><span id="line-1208">      }</span>
+<span class="source-line-no">1209</span><span id="line-1209">      // reset the flag</span>
+<span class="source-line-no">1210</span><span id="line-1210">      flushed = false;</span>
+<span class="source-line-no">1211</span><span id="line-1211">      return true;</span>
+<span class="source-line-no">1212</span><span id="line-1212">    }</span>
+<span class="source-line-no">1213</span><span id="line-1213">    return false;</span>
+<span class="source-line-no">1214</span><span id="line-1214">  }</span>
+<span class="source-line-no">1215</span><span id="line-1215"></span>
+<span class="source-line-no">1216</span><span id="line-1216">  /**</span>
+<span class="source-line-no">1217</span><span id="line-1217">   * Seek storefiles in parallel to optimize IO latency as much as possible</span>
+<span class="source-line-no">1218</span><span id="line-1218">   * @param scanners the list {@link KeyValueScanner}s to be read from</span>
+<span class="source-line-no">1219</span><span id="line-1219">   * @param kv       the KeyValue on which the operation is being requested</span>
+<span class="source-line-no">1220</span><span id="line-1220">   */</span>
+<span class="source-line-no">1221</span><span id="line-1221">  private void parallelSeek(final List&lt;? extends KeyValueScanner&gt; scanners, final ExtendedCell kv)</span>
+<span class="source-line-no">1222</span><span id="line-1222">    throws IOException {</span>
+<span class="source-line-no">1223</span><span id="line-1223">    if (scanners.isEmpty()) return;</span>
+<span class="source-line-no">1224</span><span id="line-1224">    int storeFileScannerCount = scanners.size();</span>
+<span class="source-line-no">1225</span><span id="line-1225">    CountDownLatch latch = new CountDownLatch(storeFileScannerCount);</span>
+<span class="source-line-no">1226</span><span id="line-1226">    List&lt;ParallelSeekHandler&gt; handlers = new ArrayList&lt;&gt;(storeFileScannerCount);</span>
+<span class="source-line-no">1227</span><span id="line-1227">    for (KeyValueScanner scanner : scanners) {</span>
+<span class="source-line-no">1228</span><span id="line-1228">      if (scanner instanceof StoreFileScanner) {</span>
+<span class="source-line-no">1229</span><span id="line-1229">        ParallelSeekHandler seekHandler = new ParallelSeekHandler(scanner, kv, this.readPt, latch);</span>
+<span class="source-line-no">1230</span><span id="line-1230">        executor.submit(seekHandler);</span>
+<span class="source-line-no">1231</span><span id="line-1231">        handlers.add(seekHandler);</span>
+<span class="source-line-no">1232</span><span id="line-1232">      } else {</span>
+<span class="source-line-no">1233</span><span id="line-1233">        scanner.seek(kv);</span>
+<span class="source-line-no">1234</span><span id="line-1234">        latch.countDown();</span>
+<span class="source-line-no">1235</span><span id="line-1235">      }</span>
+<span class="source-line-no">1236</span><span id="line-1236">    }</span>
+<span class="source-line-no">1237</span><span id="line-1237"></span>
+<span class="source-line-no">1238</span><span id="line-1238">    try {</span>
+<span class="source-line-no">1239</span><span id="line-1239">      latch.await();</span>
+<span class="source-line-no">1240</span><span id="line-1240">    } catch (InterruptedException ie) {</span>
+<span class="source-line-no">1241</span><span id="line-1241">      throw (InterruptedIOException) new InterruptedIOException().initCause(ie);</span>
+<span class="source-line-no">1242</span><span id="line-1242">    }</span>
+<span class="source-line-no">1243</span><span id="line-1243"></span>
+<span class="source-line-no">1244</span><span id="line-1244">    for (ParallelSeekHandler handler : handlers) {</span>
+<span class="source-line-no">1245</span><span id="line-1245">      if (handler.getErr() != null) {</span>
+<span class="source-line-no">1246</span><span id="line-1246">        throw new IOException(handler.getErr());</span>
+<span class="source-line-no">1247</span><span id="line-1247">      }</span>
+<span class="source-line-no">1248</span><span id="line-1248">    }</span>
+<span class="source-line-no">1249</span><span id="line-1249">  }</span>
+<span class="source-line-no">1250</span><span id="line-1250"></span>
+<span class="source-line-no">1251</span><span id="line-1251">  /**</span>
+<span class="source-line-no">1252</span><span id="line-1252">   * Used in testing.</span>
+<span class="source-line-no">1253</span><span id="line-1253">   * @return all scanners in no particular order</span>
+<span class="source-line-no">1254</span><span id="line-1254">   */</span>
+<span class="source-line-no">1255</span><span id="line-1255">  List&lt;KeyValueScanner&gt; getAllScannersForTesting() {</span>
+<span class="source-line-no">1256</span><span id="line-1256">    List&lt;KeyValueScanner&gt; allScanners = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">1257</span><span id="line-1257">    KeyValueScanner current = heap.getCurrentForTesting();</span>
+<span class="source-line-no">1258</span><span id="line-1258">    if (current != null) allScanners.add(current);</span>
+<span class="source-line-no">1259</span><span id="line-1259">    for (KeyValueScanner scanner : heap.getHeap())</span>
+<span class="source-line-no">1260</span><span id="line-1260">      allScanners.add(scanner);</span>
+<span class="source-line-no">1261</span><span id="line-1261">    return allScanners;</span>
+<span class="source-line-no">1262</span><span id="line-1262">  }</span>
+<span class="source-line-no">1263</span><span id="line-1263"></span>
+<span class="source-line-no">1264</span><span id="line-1264">  static void enableLazySeekGlobally(boolean enable) {</span>
+<span class="source-line-no">1265</span><span id="line-1265">    lazySeekEnabledGlobally = enable;</span>
+<span class="source-line-no">1266</span><span id="line-1266">  }</span>
+<span class="source-line-no">1267</span><span id="line-1267"></span>
+<span class="source-line-no">1268</span><span id="line-1268">  /** Returns The estimated number of KVs seen by this scanner (includes some skipped KVs). */</span>
+<span class="source-line-no">1269</span><span id="line-1269">  public long getEstimatedNumberOfKvsScanned() {</span>
+<span class="source-line-no">1270</span><span id="line-1270">    return this.kvsScanned;</span>
+<span class="source-line-no">1271</span><span id="line-1271">  }</span>
+<span class="source-line-no">1272</span><span id="line-1272"></span>
+<span class="source-line-no">1273</span><span id="line-1273">  @Override</span>
+<span class="source-line-no">1274</span><span id="line-1274">  public ExtendedCell getNextIndexedKey() {</span>
+<span class="source-line-no">1275</span><span id="line-1275">    return this.heap.getNextIndexedKey();</span>
+<span class="source-line-no">1276</span><span id="line-1276">  }</span>
+<span class="source-line-no">1277</span><span id="line-1277"></span>
+<span class="source-line-no">1278</span><span id="line-1278">  @Override</span>
+<span class="source-line-no">1279</span><span id="line-1279">  public void shipped() throws IOException {</span>
+<span class="source-line-no">1280</span><span id="line-1280">    if (prevCell != null) {</span>
+<span class="source-line-no">1281</span><span id="line-1281">      // Do the copy here so that in case the prevCell ref is pointing to the previous</span>
+<span class="source-line-no">1282</span><span id="line-1282">      // blocks we can safely release those blocks.</span>
+<span class="source-line-no">1283</span><span id="line-1283">      // This applies to blocks that are got from Bucket cache, L1 cache and the blocks</span>
+<span class="source-line-no">1284</span><span id="line-1284">      // fetched from HDFS. Copying this would ensure that we let go the references to these</span>
+<span class="source-line-no">1285</span><span id="line-1285">      // blocks so that they can be GCed safely(in case of bucket cache)</span>
+<span class="source-line-no">1286</span><span id="line-1286">      prevCell = KeyValueUtil.toNewKeyCell(this.prevCell);</span>
+<span class="source-line-no">1287</span><span id="line-1287">    }</span>
+<span class="source-line-no">1288</span><span id="line-1288">    matcher.beforeShipped();</span>
+<span class="source-line-no">1289</span><span id="line-1289">    // There wont be further fetch of Cells from these scanners. Just close.</span>
+<span class="source-line-no">1290</span><span id="line-1290">    clearAndClose(scannersForDelayedClose);</span>
+<span class="source-line-no">1291</span><span id="line-1291">    if (this.heap != null) {</span>
+<span class="source-line-no">1292</span><span id="line-1292">      this.heap.shipped();</span>
+<span class="source-line-no">1293</span><span id="line-1293">      // When switching from pread to stream, we will open a new scanner for each store file, but</span>
+<span class="source-line-no">1294</span><span id="line-1294">      // the old scanner may still track the HFileBlocks we have scanned but not sent back to client</span>
+<span class="source-line-no">1295</span><span id="line-1295">      // yet. If we close the scanner immediately then the HFileBlocks may be messed up by others</span>
+<span class="source-line-no">1296</span><span id="line-1296">      // before we serialize and send it back to client. The HFileBlocks will be released in shipped</span>
+<span class="source-line-no">1297</span><span id="line-1297">      // method, so we here will also open new scanners and close old scanners in shipped method.</span>
+<span class="source-line-no">1298</span><span id="line-1298">      // See HBASE-18055 for more details.</span>
+<span class="source-line-no">1299</span><span id="line-1299">      trySwitchToStreamRead();</span>
+<span class="source-line-no">1300</span><span id="line-1300">    }</span>
+<span class="source-line-no">1301</span><span id="line-1301">  }</span>
+<span class="source-line-no">1302</span><span id="line-1302"></span>
+<span class="source-line-no">1303</span><span id="line-1303">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
+<span class="source-line-no">1304</span><span id="line-1304">  static final void instrument() {</span>
+<span class="source-line-no">1305</span><span id="line-1305">    hasUpdatedReaders = new AtomicBoolean(false);</span>
+<span class="source-line-no">1306</span><span id="line-1306">    hasSwitchedToStreamRead = new AtomicBoolean(false);</span>
+<span class="source-line-no">1307</span><span id="line-1307">  }</span>
+<span class="source-line-no">1308</span><span id="line-1308"></span>
+<span class="source-line-no">1309</span><span id="line-1309">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
+<span class="source-line-no">1310</span><span id="line-1310">  static final boolean hasUpdatedReaders() {</span>
+<span class="source-line-no">1311</span><span id="line-1311">    return hasUpdatedReaders.get();</span>
+<span class="source-line-no">1312</span><span id="line-1312">  }</span>
+<span class="source-line-no">1313</span><span id="line-1313"></span>
+<span class="source-line-no">1314</span><span id="line-1314">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
+<span class="source-line-no">1315</span><span id="line-1315">  static final boolean hasSwitchedToStreamRead() {</span>
+<span class="source-line-no">1316</span><span id="line-1316">    return hasSwitchedToStreamRead.get();</span>
+<span class="source-line-no">1317</span><span id="line-1317">  }</span>
+<span class="source-line-no">1318</span><span id="line-1318"></span>
+<span class="source-line-no">1319</span><span id="line-1319">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
+<span class="source-line-no">1320</span><span id="line-1320">  static final void resetHasUpdatedReaders() {</span>
+<span class="source-line-no">1321</span><span id="line-1321">    hasUpdatedReaders.set(false);</span>
+<span class="source-line-no">1322</span><span id="line-1322">  }</span>
+<span class="source-line-no">1323</span><span id="line-1323"></span>
+<span class="source-line-no">1324</span><span id="line-1324">  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.UNITTEST)</span>
+<span class="source-line-no">1325</span><span id="line-1325">  static final void resetHasSwitchedToStreamRead() {</span>
+<span class="source-line-no">1326</span><span id="line-1326">    hasSwitchedToStreamRead.set(false);</span>
+<span class="source-line-no">1327</span><span id="line-1327">  }</span>
+<span class="source-line-no">1328</span><span id="line-1328">}</span>
 
 
 
diff --git a/hbase-website/dependency-convergence.html b/hbase-website/dependency-convergence.html
index a9a09e44eac..72cc661b4e2 100644
--- a/hbase-website/dependency-convergence.html
+++ b/hbase-website/dependency-convergence.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-convergence at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-convergence at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/dependency-info.html b/hbase-website/dependency-info.html
index e0fe7bde829..5f5d35eb462 100644
--- a/hbase-website/dependency-info.html
+++ b/hbase-website/dependency-info.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-info at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-info at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/dependency-management.html b/hbase-website/dependency-management.html
index 7254fb9cb71..33bf98c39b7 100644
--- a/hbase-website/dependency-management.html
+++ b/hbase-website/dependency-management.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-management at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-management at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/index.html b/hbase-website/index.html
index e981cab9fdf..9b61e7987dc 100644
--- a/hbase-website/index.html
+++ b/hbase-website/index.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:index at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:index at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/issue-management.html b/hbase-website/issue-management.html
index 0f7f673ee17..78fc25b9871 100644
--- a/hbase-website/issue-management.html
+++ b/hbase-website/issue-management.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:issue-management at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:issue-management at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/licenses.html b/hbase-website/licenses.html
index 00cb343263c..14fd2a8e5cf 100644
--- a/hbase-website/licenses.html
+++ b/hbase-website/licenses.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:licenses at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:licenses at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/mailing-lists.html b/hbase-website/mailing-lists.html
index d2e662d4e61..e8effda8a90 100644
--- a/hbase-website/mailing-lists.html
+++ b/hbase-website/mailing-lists.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:mailing-lists at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:mailing-lists at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/plugin-management.html b/hbase-website/plugin-management.html
index 3f5d397eeb8..eb35cc06294 100644
--- a/hbase-website/plugin-management.html
+++ b/hbase-website/plugin-management.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugin-management at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugin-management at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/plugins.html b/hbase-website/plugins.html
index 64e997ec22c..a7824e8739d 100644
--- a/hbase-website/plugins.html
+++ b/hbase-website/plugins.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugins at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugins at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/project-info.html b/hbase-website/project-info.html
index 6a95645564f..6476847890e 100644
--- a/hbase-website/project-info.html
+++ b/hbase-website/project-info.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-site-plugin:3.21.0:project-info at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-site-plugin:3.21.0:project-info at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/scm.html b/hbase-website/scm.html
index 5860b672181..5a9a9b30101 100644
--- a/hbase-website/scm.html
+++ b/hbase-website/scm.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:scm at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:scm at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/summary.html b/hbase-website/summary.html
index 703431273cf..9420585fb95 100644
--- a/hbase-website/summary.html
+++ b/hbase-website/summary.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:summary at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:summary at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/team.html b/hbase-website/team.html
index b8f348c0b00..93911e26810 100644
--- a/hbase-website/team.html
+++ b/hbase-website/team.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:team at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:team at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/issue-management.html b/issue-management.html
index 8fd10032b8a..a841595c371 100644
--- a/issue-management.html
+++ b/issue-management.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:issue-management at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:issue-management at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/licenses.html b/licenses.html
index 46404570d38..53cc23291b4 100644
--- a/licenses.html
+++ b/licenses.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:licenses at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:licenses at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/mailing-lists.html b/mailing-lists.html
index 4e2c6f1b1f6..7cbd4b1d0e2 100644
--- a/mailing-lists.html
+++ b/mailing-lists.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:mailing-lists at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:mailing-lists at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/plugin-management.html b/plugin-management.html
index 974e3a73b0d..1f7f356a36d 100644
--- a/plugin-management.html
+++ b/plugin-management.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugin-management at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugin-management at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/plugins.html b/plugins.html
index a4569091f48..d0d1c49897e 100644
--- a/plugins.html
+++ b/plugins.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugins at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugins at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/project-info.html b/project-info.html
index ddaf0c8ea76..c859036baa5 100644
--- a/project-info.html
+++ b/project-info.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-site-plugin:3.21.0:project-info at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-site-plugin:3.21.0:project-info at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/project-reports.html b/project-reports.html
index 294c75d5c86..76c83493692 100644
--- a/project-reports.html
+++ b/project-reports.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-site-plugin:3.21.0:project-reports at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-site-plugin:3.21.0:project-reports at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/scm.html b/scm.html
index 1aaf45c9e08..a111582fdc9 100644
--- a/scm.html
+++ b/scm.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:scm at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:scm at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/summary.html b/summary.html
index f43e7d59695..c0e438679b7 100644
--- a/summary.html
+++ b/summary.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:summary at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:summary at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/team.html b/team.html
index a74ef60e658..55d91606591 100644
--- a/team.html
+++ b/team.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:team at 02/25/26
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:team at 02/26/26
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">