.../hbase/codec/prefixtree/PrefixTreeSeeker.java | 14 +++++++++- .../prefixtree/decode/PrefixTreeArrayScanner.java | 30 ++++++++++++++++++---- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java b/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java index 65dd1ce..eb8c128 100644 --- a/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java +++ b/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java @@ -45,6 +45,7 @@ public class PrefixTreeSeeker implements EncodedSeeker { protected ByteBuffer block; protected boolean includeMvccVersion; protected PrefixTreeArraySearcher ptSearcher; + protected boolean movedToPrevious = false; public PrefixTreeSeeker(boolean includeMvccVersion) { this.includeMvccVersion = includeMvccVersion; @@ -119,7 +120,15 @@ public class PrefixTreeSeeker implements EncodedSeeker { @Override public boolean next() { - return ptSearcher.advance(); + if(movedToPrevious) { + ptSearcher.setMovedToPreviousAsPartOfSeek(true); + } + boolean advance = ptSearcher.advance(); + if (movedToPrevious) { + movedToPrevious = false; + ptSearcher.setMovedToPreviousAsPartOfSeek(false); + } + return advance; } // @Override @@ -202,11 +211,13 @@ public class PrefixTreeSeeker implements EncodedSeeker { } protected int seekToOrBeforeUsingPositionAtOrAfter(Cell kv, boolean seekBefore) { + movedToPrevious = false; // should probably switch this to use the seekForwardToOrBefore method CellScannerPosition position = ptSearcher.seekForwardToOrAfter(kv); if (CellScannerPosition.AT == position) { if (seekBefore) { + // We need not set movedToPrevious because the intention is to seekBefore ptSearcher.previous(); return 1; } @@ -217,6 +228,7 @@ public class PrefixTreeSeeker implements EncodedSeeker { if (CellScannerPosition.AFTER == position) { if (!ptSearcher.isBeforeFirst()) { ptSearcher.previous(); + movedToPrevious = true; } return 1; } diff --git a/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/decode/PrefixTreeArrayScanner.java b/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/decode/PrefixTreeArrayScanner.java index ef38f2d..c26180d 100644 --- a/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/decode/PrefixTreeArrayScanner.java +++ b/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/decode/PrefixTreeArrayScanner.java @@ -60,6 +60,7 @@ public class PrefixTreeArrayScanner extends PrefixTreeCell implements CellScanne protected boolean nubCellsRemain; protected int currentCellIndex; + protected boolean movedToPrevious; /*********************** construct ******************************/ @@ -235,7 +236,9 @@ public class PrefixTreeArrayScanner extends PrefixTreeCell implements CellScanne if (afterLast) { return false; } + boolean wasFirst = false; if (beforeFirst) { + wasFirst = true; initFirstNode(); if (currentRowNode.hasOccurrences()) { if (currentRowNode.isNub()) { @@ -245,21 +248,30 @@ public class PrefixTreeArrayScanner extends PrefixTreeCell implements CellScanne return true; } } + boolean currentNodeDiscarded = false; if (currentRowNode.isLeaf()) { discardCurrentRowNode(true); + currentNodeDiscarded = true; } while (!afterLast) { if (nubCellsRemain) { nubCellsRemain = false; } if (currentRowNode.hasMoreFanNodes()) { - followNextFan(); - if (currentRowNode.hasOccurrences()) { - currentCellIndex = 0; - return true; - }// found some values + if (!wasFirst && !currentNodeDiscarded && this.hasMovedToPreviousAsPartOfSeek()) { + followCurrentFan(); + currentNodeDiscarded = true; + } else { + followNextFan(); + if (currentRowNode.hasOccurrences()) { + currentCellIndex = 0; + return true; + }// found some values + } } else { discardCurrentRowNode(true); + // check this + //currentNodeDiscarded = true; } } return false;// went past the end @@ -526,5 +538,13 @@ public class PrefixTreeArrayScanner extends PrefixTreeCell implements CellScanne public int getTagBufferLength() { return tagsBuffer.length; } + + public void setMovedToPreviousAsPartOfSeek(boolean movedToPrevious) { + this.movedToPrevious = movedToPrevious; + } + + public boolean hasMovedToPreviousAsPartOfSeek() { + return movedToPrevious; + } }