Index: hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestQueryMatcher.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestQueryMatcher.java (revision 1532907) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestQueryMatcher.java (working copy) @@ -96,19 +96,15 @@ //Expected result List expected = new ArrayList(); - expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL); + expected.add(ScanQueryMatcher.MatchCode.SKIP); expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL); - expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL); + expected.add(ScanQueryMatcher.MatchCode.SKIP); expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL); expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW); expected.add(ScanQueryMatcher.MatchCode.DONE); // 2,4,5 - ScanQueryMatcher qm = new ScanQueryMatcher(scan, new ScanInfo(fam2, - 0, 1, ttl, false, 0, rowComparator), get.getFamilyMap().get(fam2), - EnvironmentEdgeManager.currentTimeMillis() - ttl); - List memstore = new ArrayList(); memstore.add(new KeyValue(row1, fam2, col1, 1, data)); memstore.add(new KeyValue(row1, fam2, col2, 1, data)); @@ -118,6 +114,63 @@ memstore.add(new KeyValue(row2, fam1, col1, data)); + runTest(1, memstore, expected); + + expected = new ArrayList(); + expected.add(ScanQueryMatcher.MatchCode.SKIP); + expected.add(ScanQueryMatcher.MatchCode.SKIP); + expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL); + expected.add(ScanQueryMatcher.MatchCode.SKIP); + expected.add(ScanQueryMatcher.MatchCode.SKIP); + expected.add(ScanQueryMatcher.MatchCode.SKIP); + expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL); + expected.add(ScanQueryMatcher.MatchCode.SKIP); + expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW); + expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW); + expected.add(ScanQueryMatcher.MatchCode.DONE); + + // 2,4,5 + + memstore = new ArrayList(); + memstore.add(new KeyValue(row1, fam2, col1, 1, data)); + memstore.add(new KeyValue(row1, fam2, col1, 2, data)); + memstore.add(new KeyValue(row1, fam2, col2, 1, data)); + memstore.add(new KeyValue(row1, fam2, col2, 2, data)); + memstore.add(new KeyValue(row1, fam2, col3, 1, data)); + memstore.add(new KeyValue(row1, fam2, col3, 2, data)); + memstore.add(new KeyValue(row1, fam2, col4, 1, data)); + memstore.add(new KeyValue(row1, fam2, col4, 2, data)); + memstore.add(new KeyValue(row1, fam2, col5, 1, data)); + memstore.add(new KeyValue(row1, fam2, col5, 2, data)); + + memstore.add(new KeyValue(row2, fam1, col1, data)); + runTest(1, memstore, expected); + + expected = new ArrayList(); + expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL); + expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL); + expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL); + expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL); + expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL); + expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL); + expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL); + expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL); + expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW); + expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW); + expected.add(ScanQueryMatcher.MatchCode.DONE); + + // 2,4,5 + + // test with 2 versions + runTest(2, memstore, expected); + } + + private void runTest(int maxVersions, List memstore, + List expected) throws IOException { + ScanQueryMatcher qm = new ScanQueryMatcher(scan, new ScanInfo(fam2, + 0, maxVersions, ttl, false, 0, rowComparator), get.getFamilyMap().get(fam2), + EnvironmentEdgeManager.currentTimeMillis() - ttl); + List actual = new ArrayList(); KeyValue k = memstore.get(0); qm.setRow(k.getBuffer(), k.getRowOffset(), k.getRowLength()); @@ -196,7 +249,7 @@ long testTTL = 1000; MatchCode [] expected = new MatchCode[] { - ScanQueryMatcher.MatchCode.SEEK_NEXT_COL, + ScanQueryMatcher.MatchCode.SKIP, ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL, ScanQueryMatcher.MatchCode.SEEK_NEXT_COL, ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL, Index: hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java (revision 1532907) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java (working copy) @@ -46,7 +46,7 @@ List scannerColumns, List expected) throws IOException { ColumnTracker exp = new ExplicitColumnTracker( - trackColumns, 0, maxVersions, Long.MIN_VALUE); + trackColumns, 0, maxVersions, maxVersions, Long.MIN_VALUE); //Initialize result @@ -80,9 +80,9 @@ columns.add(col2); columns.add(col4); List expected = new ArrayList(); - expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL); // col1 + expected.add(ScanQueryMatcher.MatchCode.SKIP); // col1 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL); // col2 - expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL); // col3 + expected.add(ScanQueryMatcher.MatchCode.SKIP); // col3 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW); // col4 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW); // col5 int maxVersions = 1; @@ -96,8 +96,35 @@ scanner.add(col5); runTest(maxVersions, columns, scanner, expected); - } + // test with multiple versions in store and 1 version in tracker + scanner = new ArrayList(); + scanner.add(col1); + scanner.add(col1); + scanner.add(col2); + scanner.add(col2); + scanner.add(col3); + scanner.add(col3); + scanner.add(col4); + scanner.add(col4); + scanner.add(col5); + scanner.add(col5); + + expected = new ArrayList(); + expected.add(ScanQueryMatcher.MatchCode.SKIP); // col1 + expected.add(ScanQueryMatcher.MatchCode.SKIP); // col1 + expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL); // col2 + expected.add(ScanQueryMatcher.MatchCode.SKIP); // col2 + expected.add(ScanQueryMatcher.MatchCode.SKIP); // col3 + expected.add(ScanQueryMatcher.MatchCode.SKIP); // col3 + expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW); // col4 + expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW); // col4 + expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW); // col5 + expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW); // col5 + + runTest(maxVersions, columns, scanner, expected); +} + public void testGet_MultiVersion() throws IOException{ if(PRINT){ System.out.println("\nMultiVersion"); @@ -164,7 +191,7 @@ columns.add(Bytes.toBytes("col"+i)); } - ColumnTracker explicit = new ExplicitColumnTracker(columns, 0, maxVersions, + ColumnTracker explicit = new ExplicitColumnTracker(columns, 0, maxVersions, maxVersions, Long.MIN_VALUE); for (int i = 0; i < 100000; i+=2) { byte [] col = Bytes.toBytes("col"+i); @@ -191,8 +218,8 @@ new byte[][] { col1, col4 }); List expected = Arrays.asList( new ScanQueryMatcher.MatchCode[] { - ScanQueryMatcher.MatchCode.SEEK_NEXT_COL, - ScanQueryMatcher.MatchCode.SEEK_NEXT_COL }); + ScanQueryMatcher.MatchCode.SKIP, + ScanQueryMatcher.MatchCode.SKIP }); runTest(1, columns, scanner, expected); } Index: hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java (revision 1532907) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java (working copy) @@ -183,8 +183,8 @@ // We can share the ExplicitColumnTracker, diff is we reset // between rows, not between storefiles. - this.columns = new ExplicitColumnTracker(columns, - scanInfo.getMinVersions(), maxVersions, oldestUnexpiredTS); + this.columns = new ExplicitColumnTracker(columns, scanInfo.getMinVersions(), maxVersions, + scanInfo.getMaxVersions(), oldestUnexpiredTS); } } Index: hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java (revision 1532907) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java (working copy) @@ -56,6 +56,7 @@ public class ExplicitColumnTracker implements ColumnTracker { private final int maxVersions; + private final int storeMaxVersions; // max version as set by the CF private final int minVersions; /** @@ -80,8 +81,9 @@ * based on TTL */ public ExplicitColumnTracker(NavigableSet columns, int minVersions, - int maxVersions, long oldestUnexpiredTS) { + int maxVersions, int storeMaxVersions, long oldestUnexpiredTS) { this.maxVersions = maxVersions; + this.storeMaxVersions = storeMaxVersions; this.minVersions = minVersions; this.oldestStamp = oldestUnexpiredTS; this.columns = new ArrayList(columns.size()); @@ -136,8 +138,9 @@ if (ret > 0) { // The current KV is smaller than the column the ExplicitColumnTracker - // is interested in, so seek to that column of interest. - return ScanQueryMatcher.MatchCode.SEEK_NEXT_COL; + // is interested in, so skip or seek to that column of interest. + return storeMaxVersions == 1 ? ScanQueryMatcher.MatchCode.SKIP + : ScanQueryMatcher.MatchCode.SEEK_NEXT_COL; } // The current KV is bigger than the column the ExplicitColumnTracker