.../hadoop/hbase/regionserver/SegmentScanner.java | 76 ++++++++++++++-------- 1 file changed, 50 insertions(+), 26 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..e8d9af0 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,10 @@ 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 + // while doing seekToPreviousRow + private Cell nextRowCell = null; + int count = 0; protected SegmentScanner(Segment segment, long readPoint) { this(segment, readPoint, DEFAULT_SCANNER_ORDER); @@ -174,28 +178,37 @@ public class SegmentScanner implements KeyValueScanner { public boolean seekToPreviousRow(Cell cell) throws IOException { boolean keepSeeking; Cell key = cell; - do { - Cell firstKeyOnRow = CellUtil.createFirstOnRow(key); - SortedSet cellHead = segment.headSet(firstKeyOnRow); - Cell lastCellBeforeRow = cellHead.isEmpty() ? null : cellHead.last(); - if (lastCellBeforeRow == null) { - current = null; - return false; - } - Cell firstKeyOnPreviousRow = CellUtil.createFirstOnRow(lastCellBeforeRow); - this.stopSkippingKVsIfNextRow = true; - seek(firstKeyOnPreviousRow); - this.stopSkippingKVsIfNextRow = false; - if (peek() == null - || segment.getComparator().compareRows(peek(), firstKeyOnPreviousRow) > 0) { - keepSeeking = true; - key = firstKeyOnPreviousRow; - continue; - } else { - keepSeeking = false; - } - } while (keepSeeking); - return true; + try { + nextRowCell = null; + do { + Cell firstKeyOnRow = CellUtil.createFirstOnRow(key); + SortedSet cellHead = segment.headSet(firstKeyOnRow); + Cell lastCellBeforeRow = cellHead.isEmpty() ? null : cellHead.last(); + if (lastCellBeforeRow == null) { + current = null; + return false; + } + Cell firstKeyOnPreviousRow = CellUtil.createFirstOnRow(lastCellBeforeRow); + this.stopSkippingKVsIfNextRow = true; + seek(firstKeyOnPreviousRow); + this.stopSkippingKVsIfNextRow = false; + if (peek() == null + || segment.getComparator().compareRows(peek(), firstKeyOnPreviousRow) > 0) { + keepSeeking = true; + key = firstKeyOnPreviousRow; + continue; + } else { + keepSeeking = false; + } + } while (keepSeeking); + return true; + } finally { + // nullify this so that this nextRowCell is set only for + // seekToPreviousRow + nextRowCell = null; + System.out.println(count); + count = 0; + } } /** @@ -332,15 +345,26 @@ 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 + count++; + 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) { + if (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 } finally { if (next != null) {