You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ns...@apache.org on 2011/10/18 23:02:09 UTC

svn commit: r1185856 - in /hbase/branches/0.89-fb/src: main/java/org/apache/hadoop/hbase/regionserver/ test/java/org/apache/hadoop/hbase/regionserver/

Author: nspiegelberg
Date: Tue Oct 18 21:02:08 2011
New Revision: 1185856

URL: http://svn.apache.org/viewvc?rev=1185856&view=rev
Log:
HBASE-4585 Avoid seek operation when current kv is deleted

Modified:
    hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/DeleteTracker.java
    hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java
    hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
    hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/regionserver/TestBlocksRead.java
    hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/regionserver/TestScanDeleteTracker.java

Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/DeleteTracker.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/DeleteTracker.java?rev=1185856&r1=1185855&r2=1185856&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/DeleteTracker.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/DeleteTracker.java Tue Oct 18 21:02:08 2011
@@ -51,9 +51,9 @@ public interface DeleteTracker {
    * @param qualifierOffset column qualifier offset
    * @param qualifierLength column qualifier length
    * @param timestamp timestamp
-   * @return true is the specified KeyValue is deleted, false if not
+   * @return deleteResult The result tells whether the KeyValue is deleted and why
    */
-  public boolean isDeleted(byte [] buffer, int qualifierOffset,
+  public DeleteResult isDeleted(byte [] buffer, int qualifierOffset,
       int qualifierLength, long timestamp);
 
   /**
@@ -94,4 +94,17 @@ public interface DeleteTracker {
     NEXT_NEW
   }
 
+  /**
+   * Returns codes for delete result.
+   * The codes tell the ScanQueryMatcher whether the kv is deleted and why.
+   * Based on the delete result, the ScanQueryMatcher will decide the next
+   * operation
+   */
+  public static enum DeleteResult {
+    FAMILY_DELETED, // The KeyValue is deleted by a delete family.
+    COLUMN_DELETED, // The KeyValue is deleted by a delete column.
+    VERSION_DELETED, // The KeyValue is deleted by a version delete.
+    NOT_DELETED
+  }
+
 }

Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java?rev=1185856&r1=1185855&r2=1185856&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java Tue Oct 18 21:02:08 2011
@@ -21,6 +21,7 @@
 package org.apache.hadoop.hbase.regionserver;
 
 import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.regionserver.DeleteTracker.DeleteResult;
 import org.apache.hadoop.hbase.util.Bytes;
 
 /**
@@ -99,13 +100,13 @@ public class ScanDeleteTracker implement
    * @param qualifierOffset column qualifier offset
    * @param qualifierLength column qualifier length
    * @param timestamp timestamp
-   * @return true is the specified KeyValue is deleted, false if not
+   * @return deleteResult
    */
   @Override
-  public boolean isDeleted(byte [] buffer, int qualifierOffset,
+  public DeleteResult isDeleted(byte [] buffer, int qualifierOffset,
       int qualifierLength, long timestamp) {
     if (timestamp <= familyStamp) {
-      return true;
+      return DeleteResult.FAMILY_DELETED;
     }
 
     if (deleteBuffer != null) {
@@ -114,12 +115,12 @@ public class ScanDeleteTracker implement
 
       if (ret == 0) {
         if (deleteType == KeyValue.Type.DeleteColumn.getCode()) {
-          return true;
+          return DeleteResult.COLUMN_DELETED;
         }
         // Delete (aka DeleteVersion)
         // If the timestamp is the same, keep this one
         if (timestamp == deleteTimestamp) {
-          return true;
+          return DeleteResult.VERSION_DELETED;
         }
         // use assert or not?
         assert timestamp < deleteTimestamp;
@@ -138,7 +139,7 @@ public class ScanDeleteTracker implement
       }
     }
 
-    return false;
+    return DeleteResult.NOT_DELETED;
   }
 
   @Override

Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java?rev=1185856&r1=1185855&r2=1185856&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java Tue Oct 18 21:02:08 2011
@@ -26,6 +26,7 @@ import org.apache.hadoop.hbase.client.Sc
 import org.apache.hadoop.hbase.filter.Filter;
 import org.apache.hadoop.hbase.filter.Filter.ReturnCode;
 import org.apache.hadoop.hbase.io.TimeRange;
+import org.apache.hadoop.hbase.regionserver.DeleteTracker.DeleteResult;
 import org.apache.hadoop.hbase.util.Bytes;
 
 import java.io.IOException;
@@ -181,15 +182,21 @@ public class ScanQueryMatcher {
       }
     }
 
-    if (!this.deletes.isEmpty() &&
-        deletes.isDeleted(bytes, offset, qualLength, timestamp)) {
-
-      // May be able to optimize the SKIP here, if we matched
-      // due to a DelFam, we can skip to next row
-      // due to a DelCol, we can skip to next col
-      // But it requires more info out of isDelete().
-      // needful -> million column challenge.
-      return MatchCode.SKIP;
+    if (!this.deletes.isEmpty()) {
+      DeleteResult deleteResult = deletes.isDeleted(bytes, offset, qualLength,
+          timestamp);
+
+      switch (deleteResult) {
+        case FAMILY_DELETED:
+        case COLUMN_DELETED:
+          return getNextRowOrNextColumn(bytes, offset, qualLength);
+        case VERSION_DELETED:
+          return MatchCode.SKIP;
+        case NOT_DELETED:
+          break;
+        default:
+          throw new RuntimeException("UNEXPECTED");
+        }
     }
 
     int timestampComparison = tr.compare(timestamp);

Modified: hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/regionserver/TestBlocksRead.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/regionserver/TestBlocksRead.java?rev=1185856&r1=1185855&r2=1185856&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/regionserver/TestBlocksRead.java (original)
+++ hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/regionserver/TestBlocksRead.java Tue Oct 18 21:02:08 2011
@@ -291,16 +291,14 @@ public class TestBlocksRead extends HBas
     deleteFamily(FAMILY, "row", 6);
     region.flushcache();
 
-    // Expected blocks read: 6. Why? [TODO]
-    // With lazy seek, would have expected this to be lower.
-    // At least is shouldn't be worse than before.
-    kvs = getData(FAMILY, "row", "col1", 5);
+    // Expected blocks read: 2. [HBASE-4585]
+    kvs = getData(FAMILY, "row", "col1", 2);
     assertEquals(0, kvs.length);
-    kvs = getData(FAMILY, "row", "col2", 5);
+    kvs = getData(FAMILY, "row", "col2", 3);
     assertEquals(0, kvs.length);
     kvs = getData(FAMILY, "row", "col3", 2);
     assertEquals(0, kvs.length);
-    kvs = getData(FAMILY, "row", Arrays.asList("col1", "col2", "col3"), 6);
+    kvs = getData(FAMILY, "row", Arrays.asList("col1", "col2", "col3"), 4);
     assertEquals(0, kvs.length);
 
     // File 5: Delete with post data timestamp and insert some older
@@ -312,11 +310,8 @@ public class TestBlocksRead extends HBas
     putData(FAMILY, "row", "col3", 9);
     region.flushcache();
 
-    // Expected blocks read: 10. Why? [TODO]
-    // With lazy seek, would have expected this to be lower.
-    // At least is shouldn't be worse than before.
-    //
-    kvs = getData(FAMILY, "row", Arrays.asList("col1", "col2", "col3"), 10);
+    // Expected blocks read: 5. [HBASE-4585]
+    kvs = getData(FAMILY, "row", Arrays.asList("col1", "col2", "col3"), 5);
     assertEquals(0, kvs.length);
 
     // File 6: Put back new data
@@ -325,13 +320,7 @@ public class TestBlocksRead extends HBas
     putData(FAMILY, "row", "col3", 13);
     region.flushcache();
 
-    // Expected blocks read: 9. Why? [TOD0]
-    //
-    // [Would have expected this to be 8.
-    //  Six to go to the top of each file for delete marker. On file 6, the
-    //  top block would serve "col1". And we should need two more to
-    //  serve col2 and col3 from file 6.
-    //
+    // Expected blocks read: 5. [HBASE-4585]
     kvs = getData(FAMILY, "row", Arrays.asList("col1", "col2", "col3"), 5);
     assertEquals(3, kvs.length);
     verifyData(kvs[0], "row", "col1", 11);

Modified: hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/regionserver/TestScanDeleteTracker.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/regionserver/TestScanDeleteTracker.java?rev=1185856&r1=1185855&r2=1185856&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/regionserver/TestScanDeleteTracker.java (original)
+++ hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/regionserver/TestScanDeleteTracker.java Tue Oct 18 21:02:08 2011
@@ -23,6 +23,7 @@ package org.apache.hadoop.hbase.regionse
 import org.apache.hadoop.hbase.HBaseTestCase;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.regionserver.DeleteTracker.DeleteResult;
 import org.apache.hadoop.hbase.util.Bytes;
 
 
@@ -42,8 +43,8 @@ public class TestScanDeleteTracker exten
     deleteType = KeyValue.Type.Delete.getCode();
 
     sdt.add(qualifier, 0, qualifier.length, timestamp, deleteType);
-    boolean ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
-    assertEquals(true, ret);
+    DeleteResult ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
+    assertEquals(DeleteResult.VERSION_DELETED, ret);
   }
 
   public void testDeletedBy_DeleteColumn() {
@@ -52,8 +53,8 @@ public class TestScanDeleteTracker exten
 
     sdt.add(qualifier, 0, qualifier.length, timestamp, deleteType);
     timestamp -= 5;
-    boolean ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
-    assertEquals(true, ret);
+    DeleteResult ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
+    assertEquals(DeleteResult.COLUMN_DELETED, ret);
   }
 
   public void testDeletedBy_DeleteFamily() {
@@ -63,8 +64,8 @@ public class TestScanDeleteTracker exten
     sdt.add(qualifier, 0, qualifier.length, timestamp, deleteType);
 
     timestamp -= 5;
-    boolean ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
-    assertEquals(true, ret);
+    DeleteResult ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
+    assertEquals(DeleteResult.FAMILY_DELETED, ret);
   }
 
   public void testDelete_DeleteColumn() {
@@ -78,8 +79,8 @@ public class TestScanDeleteTracker exten
     sdt.add(qualifier, 0, qualifier.length, timestamp, deleteType);
 
     timestamp -= 5;
-    boolean ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
-    assertEquals(true, ret);
+    DeleteResult ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
+    assertEquals(DeleteResult.COLUMN_DELETED, ret);
   }
 
 
@@ -93,8 +94,8 @@ public class TestScanDeleteTracker exten
     deleteType = KeyValue.Type.Delete.getCode();
     sdt.add(qualifier, 0, qualifier.length, timestamp, deleteType);
 
-    boolean ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
-    assertEquals(true, ret);
+    DeleteResult ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
+    assertEquals( DeleteResult.VERSION_DELETED, ret);
   }
 
   //Testing new way where we save the Delete in case of a Delete for specific
@@ -109,5 +110,4 @@ public class TestScanDeleteTracker exten
     assertEquals(false ,sdt.isEmpty());
   }
 
-
 }