Author: stack
Date: Tue Sep 27 18:42:31 2011
New Revision: 1176514

URL: http://svn.apache.org/viewvc?rev=1176514&view=rev
Log:
HBASE-4433: avoid extra next (potentially a seek) if done with column/row

Modified:
    hbase/branches/0.92/CHANGES.txt
    
hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java
    
hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
    
hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java
    
hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestBlocksRead.java
    
hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java
    
hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestQueryMatcher.java

Modified: hbase/branches/0.92/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.92/CHANGES.txt?rev=1176514&r1=1176513&r2=1176514&view=diff
==============================================================================
--- hbase/branches/0.92/CHANGES.txt (original)
+++ hbase/branches/0.92/CHANGES.txt Tue Sep 27 18:42:31 2011
@@ -634,6 +634,8 @@ Release 0.90.5 - Unreleased
                (Lars Hofhansl)
    HBASE-4295  rowcounter does not return the correct number of rows in
                certain circumstances (David Revell)
+   HBASE-4433  avoid extra next (potentially a seek) if done with column/row
+               (Kannan Muthukkaruppan)
 
   IMPROVEMENT
    HBASE-4205  Enhance HTable javadoc (Eric Charles)

Modified: 
hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java?rev=1176514&r1=1176513&r2=1176514&view=diff
==============================================================================
--- 
hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java
 (original)
+++ 
hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java
 Tue Sep 27 18:42:31 2011
@@ -50,6 +50,12 @@ public class ExplicitColumnTracker imple
 
   private final int maxVersions;
   private final int minVersions;
+
+ /**
+  * Contains the list of columns that the ExplicitColumnTracker is tracking.
+  * Each ColumnCount instance also tracks how many versions of the requested
+  * column have been returned.
+  */
   private final List<ColumnCount> columns;
   private final List<ColumnCount> columnsToReuse;
   private int index;
@@ -127,13 +133,22 @@ public class ExplicitColumnTracker imple
         int count = this.column.increment();
         if(count >= maxVersions || (count >= minVersions && 
isExpired(timestamp))) {
           // Done with versions for this column
+          // Note: because we are done with this column, and are removing
+          // it from columns, we don't do a ++this.index. The index stays
+          // the same but the columns have shifted within the array such
+          // that index now points to the next column we are interested in.
           this.columns.remove(this.index);
+
           resetTS();
-          if(this.columns.size() == this.index) {
-            // Will not hit any more columns in this storefile
+          if (this.columns.size() == this.index) {
+            // We have served all the requested columns.
             this.column = null;
+           return ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW;
           } else {
+           // We are done with current column; advance to next column
+           // of interest.
             this.column = this.columns.get(this.index);
+           return ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL;
           }
         } else {
           setTS(timestamp);
@@ -144,15 +159,18 @@ public class ExplicitColumnTracker imple
       resetTS();
 
       if (ret > 0) {
-        // Specified column is smaller than the current, skip to next column.
+        // 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;
       }
 
-      // Specified column is bigger than current column
-      // Move down current column and check again
-      if(ret <= -1) {
-        if(++this.index >= this.columns.size()) {
-          // No more to match, do not include, done with storefile
+      // The current KV is bigger than the column the ExplicitColumnTracker
+      // is interested in. That means there is no more data for the column
+      // of interest. Advance the ExplicitColumnTracker state to next
+      // column of interest, and check again.
+      if (ret <= -1) {
+        if (++this.index >= this.columns.size()) {
+          // No more to match, do not include, done with this row.
           return ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW; // done_row
         }
         // This is the recursive case.

Modified: 
hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java?rev=1176514&r1=1176513&r2=1176514&view=diff
==============================================================================
--- 
hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
 (original)
+++ 
hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
 Tue Sep 27 18:42:31 2011
@@ -352,5 +352,15 @@ public class ScanQueryMatcher {
      * Seek to next key which is given as hint.
      */
     SEEK_NEXT_USING_HINT,
+
+    /**
+     * Include KeyValue and done with column, seek to next.
+     */
+    INCLUDE_AND_SEEK_NEXT_COL,
+
+    /**
+     * Include KeyValue and done with row, seek to next.
+     */
+    INCLUDE_AND_SEEK_NEXT_ROW,
   }
 }

Modified: 
hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java?rev=1176514&r1=1176513&r2=1176514&view=diff
==============================================================================
--- 
hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java
 (original)
+++ 
hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java
 Tue Sep 27 18:42:31 2011
@@ -258,8 +258,23 @@ class StoreScanner implements KeyValueSc
       //DebugPrint.println("SS peek kv = " + kv + " with qcode = " + qcode);
       switch(qcode) {
         case INCLUDE:
+        case INCLUDE_AND_SEEK_NEXT_ROW:
+        case INCLUDE_AND_SEEK_NEXT_COL:
+
           results.add(copyKv);
-          this.heap.next();
+
+          if (qcode == ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW) {
+            if (!matcher.moreRowsMayExistAfter(kv)) {
+              outResult.addAll(results);
+              return false;
+            }
+            reseek(matcher.getKeyForNextRow(kv));
+          } else if (qcode == 
ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL) {
+            reseek(matcher.getKeyForNextColumn(kv));
+          } else {
+            this.heap.next();
+          }
+
           if (limit > 0 && (results.size() == limit)) {
             break LOOP;
           }

Modified: 
hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestBlocksRead.java
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestBlocksRead.java?rev=1176514&r1=1176513&r2=1176514&view=diff
==============================================================================
--- 
hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestBlocksRead.java
 (original)
+++ 
hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestBlocksRead.java
 Tue Sep 27 18:42:31 2011
@@ -201,8 +201,8 @@ public class TestBlocksRead extends HBas
     putData(FAMILY, "row", "col7", 7);
     region.flushcache();
 
-    // Expected block reads: 2
-    kvs = getData(FAMILY, "row", "col1", 2);
+    // Expected block reads: 1
+    kvs = getData(FAMILY, "row", "col1", 1);
     assertEquals(1, kvs.length);
     verifyData(kvs[0], "row", "col1", 1);
 
@@ -218,8 +218,8 @@ public class TestBlocksRead extends HBas
     verifyData(kvs[0], "row", "col2", 2);
     verifyData(kvs[1], "row", "col3", 3);
 
-    // Expected block reads: 4
-    kvs = getData(FAMILY, "row", Arrays.asList("col5"), 4);
+    // Expected block reads: 3
+    kvs = getData(FAMILY, "row", Arrays.asList("col5"), 3);
     assertEquals(1, kvs.length);
     verifyData(kvs[0], "row", "col5", 5);
   }
@@ -248,15 +248,16 @@ public class TestBlocksRead extends HBas
     putData(FAMILY, "row", "col2", 4);
     region.flushcache();
 
-    // Baseline expected blocks read: 3
-    kvs = getData(FAMILY, "row", Arrays.asList("col1"), 3);
+    // Baseline expected blocks read: 2
+    kvs = getData(FAMILY, "row", Arrays.asList("col1"), 2);
     assertEquals(1, kvs.length);
     verifyData(kvs[0], "row", "col1", 3);
 
-    // Baseline expected blocks read: 5
+    // Baseline expected blocks read: 6
     // This increase is a minor glitch due to: HBASE-4466. Once that
-    // is fixed this will drop back. The extra access will be a cache hit.
-    kvs = getData(FAMILY, "row", Arrays.asList("col1", "col2"), 5);
+    // is fixed this will drop back. The extra access will be a cache
+    // hit.
+    kvs = getData(FAMILY, "row", Arrays.asList("col1", "col2"), 6);
     assertEquals(2, kvs.length);
     verifyData(kvs[0], "row", "col1", 3);
     verifyData(kvs[1], "row", "col2", 4);
@@ -271,8 +272,8 @@ public class TestBlocksRead extends HBas
     verifyData(kvs[0], "row", "col3", 5);
 
     // Get a column from older file.
-    // Baseline expected blocks read: 4
-    kvs = getData(FAMILY, "row", Arrays.asList("col1"), 4);
+    // Baseline expected blocks read: 3
+    kvs = getData(FAMILY, "row", Arrays.asList("col1"), 3);
     assertEquals(1, kvs.length);
     verifyData(kvs[0], "row", "col1", 3);
 
@@ -290,10 +291,12 @@ public class TestBlocksRead extends HBas
     kvs = getData(FAMILY, "row", Arrays.asList("col1", "col2", "col3"), 6);
     assertEquals(0, kvs.length);
 
-    // File 5: Delete with post data timestamp and insert some older
-    // date in new files.
+    // File 5: Delete
     deleteFamily(FAMILY, "row", 10);
     region.flushcache();
+
+    // File 6: some more puts, but with timestamps older than the
+    // previous delete.
     putData(FAMILY, "row", "col1", 7);
     putData(FAMILY, "row", "col2", 8);
     putData(FAMILY, "row", "col3", 9);
@@ -303,14 +306,17 @@ public class TestBlocksRead extends HBas
     kvs = getData(FAMILY, "row", Arrays.asList("col1", "col2", "col3"), 10);
     assertEquals(0, kvs.length);
 
-    // File 6: Put back new data
+    // File 7: Put back new data
     putData(FAMILY, "row", "col1", 11);
     putData(FAMILY, "row", "col2", 12);
     putData(FAMILY, "row", "col3", 13);
     region.flushcache();
 
-    // Baseline expected blocks read: 13
-    kvs = getData(FAMILY, "row", Arrays.asList("col1", "col2", "col3"), 13);
+    // Baseline expected blocks read: 21
+    // This increase is a minor glitch due to: HBASE-4466. Once that
+    // is fixed this will drop back. The extra access will be a cache
+    // hit. The test case only has 13 blocks altogther!
+    kvs = getData(FAMILY, "row", Arrays.asList("col1", "col2", "col3"), 21);
     assertEquals(3, kvs.length);
     verifyData(kvs[0], "row", "col1", 11);
     verifyData(kvs[1], "row", "col2", 12);

Modified: 
hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java?rev=1176514&r1=1176513&r2=1176514&view=diff
==============================================================================
--- 
hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java
 (original)
+++ 
hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java
 Tue Sep 27 18:42:31 2011
@@ -77,11 +77,11 @@ public class TestExplicitColumnTracker e
     columns.add(col2);
     columns.add(col4);
     List<MatchCode> expected = new ArrayList<ScanQueryMatcher.MatchCode>();
-    expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
-    expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
-    expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
-    expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
-    expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
+    expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);             // col1
+    expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL); // col2
+    expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);             // 
col3    
+    expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW); // col4
+    expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);             // 
col5    
     int maxVersions = 1;
 
     //Create "Scanner"
@@ -111,16 +111,16 @@ public class TestExplicitColumnTracker e
     expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
     expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
 
-    expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
-    expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
+    expected.add(ScanQueryMatcher.MatchCode.INCLUDE);                   // 
col2; 1st version
+    expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL); // 
col2; 2nd version
     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.SEEK_NEXT_COL);
 
-    expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
-    expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
+    expected.add(ScanQueryMatcher.MatchCode.INCLUDE);                   // 
col4; 1st version
+    expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW); // 
col4; 2nd version
     expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
 
     expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);

Modified: 
hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestQueryMatcher.java
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestQueryMatcher.java?rev=1176514&r1=1176513&r2=1176514&view=diff
==============================================================================
--- 
hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestQueryMatcher.java
 (original)
+++ 
hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/regionserver/TestQueryMatcher.java
 Tue Sep 27 18:42:31 2011
@@ -88,10 +88,10 @@ public class TestQueryMatcher extends HB
     //Expected result
     List<MatchCode> expected = new ArrayList<ScanQueryMatcher.MatchCode>();
     expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
-    expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
+    expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL);
     expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
-    expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
-    expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
+    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
@@ -182,9 +182,9 @@ public class TestQueryMatcher extends HB
     long testTTL = 1000;
     MatchCode [] expected = new MatchCode[] {
         ScanQueryMatcher.MatchCode.SEEK_NEXT_COL,
-        ScanQueryMatcher.MatchCode.INCLUDE,
+        ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL,
         ScanQueryMatcher.MatchCode.SEEK_NEXT_COL,
-        ScanQueryMatcher.MatchCode.INCLUDE,
+        ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL,
         ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW,
         ScanQueryMatcher.MatchCode.DONE
     };


Reply via email to