.../hadoop/hbase/regionserver/SegmentScanner.java | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SegmentScanner.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SegmentScanner.java index 8cf0a7c..90d0fab 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SegmentScanner.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SegmentScanner.java @@ -55,6 +55,8 @@ public class SegmentScanner implements KeyValueScanner { private boolean stopSkippingKVsIfNextRow = false; // last iterated KVs by seek (to restore the iterator state after reseek) private Cell last = null; + // When we continue to skip the subsequent rows if they are ignored by mvcc + private Cell nextRowCell = null; protected SegmentScanner(Segment segment, long readPoint) { this(segment, readPoint, DEFAULT_SCANNER_ORDER); @@ -95,6 +97,7 @@ public class SegmentScanner implements KeyValueScanner { @Override public Cell next() throws IOException { Cell oldCurrent = current; + nextRowCell = null; current = getNext(); // update the currently observed Cell return oldCurrent; } @@ -139,6 +142,7 @@ public class SegmentScanner implements KeyValueScanner { the reseeked set to at least that point. */ iter = segment.tailSet(getHighest(cell, last)).iterator(); + nextRowCell = null; current = getNext(); return (current != null); } @@ -174,6 +178,7 @@ public class SegmentScanner implements KeyValueScanner { public boolean seekToPreviousRow(Cell cell) throws IOException { boolean keepSeeking; Cell key = cell; + nextRowCell = null; do { Cell firstKeyOnRow = CellUtil.createFirstOnRow(key); SortedSet cellHead = segment.headSet(firstKeyOnRow); @@ -332,13 +337,22 @@ public class SegmentScanner implements KeyValueScanner { while (iter.hasNext()) { next = iter.next(); if (next.getSequenceId() <= this.readPoint) { - return next; // skip irrelevant versions + return next; // skip irrelevant versions } - if (stopSkippingKVsIfNextRow && // for backwardSeek() stay in the - startKV != null && // boundaries of a single row + if (stopSkippingKVsIfNextRow && // for backwardSeek() stay in the + startKV != null && // boundaries of a single row segment.compareRows(next, startKV) > 0) { return null; } + // This happens when startKV itself is null + if (stopSkippingKVsIfNextRow && nextRowCell != null + && segment.compareRows(next, nextRowCell) > 0) { + // If we don't have this check we keep checking every other row + // till we reach the end of the rows. + nextRowCell = next; + return null; + } + nextRowCell = next; } // end of while return null; // nothing found