Index: src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java (revision 1548777) +++ src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java (working copy) @@ -85,6 +85,12 @@ int rowOffset; short rowLength; + private byte[] currentCol; + private int currentColOff; + private int currentColLen; + private int currentColCount; + private final int storeVersions; + /** * Oldest put in any of the involved store files * Used to decide whether it is ok to delete @@ -148,6 +154,7 @@ this.earliestPutTs = earliestPutTs; this.maxReadPointToTrackVersions = readPointToUse; this.timeToPurgeDeletes = scanInfo.getTimeToPurgeDeletes(); + this.storeVersions = scanInfo.getMaxVersions(); /* how to deal with deletes */ this.isUserScan = scanType == ScanType.USER_SCAN; @@ -334,6 +341,12 @@ } } + // first check whether we should even see this KV + if (!compareQualifier(bytes, offset, qualLength) && !kv.isDelete() + && ++currentColCount > storeVersions) { + return columns.getNextRowOrNextColumn(bytes, offset, qualLength); + } + int timestampComparison = tr.compare(timestamp); if (timestampComparison >= 1) { return MatchCode.SKIP; @@ -420,13 +433,37 @@ reset(); } + public void resetCol() { + currentCol = null; + currentColOff = 0; + currentColLen = 0; + currentColCount = 0; + } + public void reset() { this.deletes.reset(); this.columns.reset(); + resetCol(); stickyNextRow = false; } + protected boolean compareQualifier(byte[] bytes, int offset, int length) { + if (currentCol == null) { + currentCol = bytes; + currentColOff = offset; + currentColLen = length; + return false; + } else { + boolean result = Bytes.equals(currentCol, currentColOff, currentColLen, bytes, offset, length); + // make sure we do not hang on to the old block for longer than needed + currentCol = bytes; + currentColOff = offset; + currentColLen = length; + return result; + } + } + /** * * @return the start key Index: src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java (revision 1548777) +++ src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java (working copy) @@ -403,6 +403,7 @@ } reseek(matcher.getKeyForNextRow(kv)); } else if (qcode == ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL) { + matcher.resetCol(); reseek(matcher.getKeyForNextColumn(kv)); } else { this.heap.next(); @@ -433,6 +434,7 @@ break; case SEEK_NEXT_COL: + matcher.resetCol(); reseek(matcher.getKeyForNextColumn(kv)); break;