You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2011/06/14 00:15:12 UTC

svn commit: r1135319 - in /hbase/trunk: ./ src/main/java/org/apache/hadoop/hbase/ src/main/java/org/apache/hadoop/hbase/catalog/ src/main/java/org/apache/hadoop/hbase/client/ src/main/java/org/apache/hadoop/hbase/io/hfile/ src/main/java/org/apache/hado...

Author: stack
Date: Mon Jun 13 22:15:11 2011
New Revision: 1135319

URL: http://svn.apache.org/viewvc?rev=1135319&view=rev
Log:
HBASE-3928 Some potential performance improvements to Bytes/KeyValue

Modified:
    hbase/trunk/CHANGES.txt
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/KeyValue.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/Bytes.java

Modified: hbase/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hbase/trunk/CHANGES.txt?rev=1135319&r1=1135318&r2=1135319&view=diff
==============================================================================
--- hbase/trunk/CHANGES.txt (original)
+++ hbase/trunk/CHANGES.txt Mon Jun 13 22:15:11 2011
@@ -256,6 +256,7 @@ Release 0.91.0 - Unreleased
    HBASE-3941  "hbase version" command line should print version info
                (Jolly Chen)
    HBASE-3961  Add Delete.setWriteToWAL functionality (Bruno Dumon)
+   HBASE-3928  Some potential performance improvements to Bytes/KeyValue
 
   TASKS
    HBASE-3559  Move report of split to master OFF the heartbeat channel

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/KeyValue.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/KeyValue.java?rev=1135319&r1=1135318&r2=1135319&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/KeyValue.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/KeyValue.java Mon Jun 13 22:15:11 2011
@@ -529,10 +529,8 @@ public class KeyValue implements Writabl
     KeyValue kv = (KeyValue)other;
     // Comparing bytes should be fine doing equals test.  Shouldn't have to
     // worry about special .META. comparators doing straight equals.
-    boolean result = Bytes.BYTES_RAWCOMPARATOR.compare(getBuffer(),
-        getKeyOffset(), getKeyLength(),
-      kv.getBuffer(), kv.getKeyOffset(), kv.getKeyLength()) == 0;
-    return result;
+    return Bytes.equals(getBuffer(), getKeyOffset(), getKeyLength(),
+      kv.getBuffer(), kv.getKeyOffset(), kv.getKeyLength());
   }
 
   public int hashCode() {
@@ -828,8 +826,8 @@ public class KeyValue implements Writabl
    * @return True if this KeyValue has a LATEST_TIMESTAMP timestamp.
    */
   public boolean isLatestTimestamp() {
-    return  Bytes.compareTo(getBuffer(), getTimestampOffset(), Bytes.SIZEOF_LONG,
-      HConstants.LATEST_TIMESTAMP_BYTES, 0, Bytes.SIZEOF_LONG) == 0;
+    return Bytes.equals(getBuffer(), getTimestampOffset(), Bytes.SIZEOF_LONG,
+      HConstants.LATEST_TIMESTAMP_BYTES, 0, Bytes.SIZEOF_LONG);
   }
 
   /**
@@ -1089,8 +1087,8 @@ public class KeyValue implements Writabl
     if (this.length == 0 || this.bytes.length == 0) {
       return false;
     }
-    return Bytes.compareTo(family, offset, length,
-        this.bytes, getFamilyOffset(), getFamilyLength()) == 0;
+    return Bytes.equals(family, offset, length,
+        this.bytes, getFamilyOffset(), getFamilyLength());
   }
 
   public boolean matchingFamily(final KeyValue other) {
@@ -1107,8 +1105,8 @@ public class KeyValue implements Writabl
   }
 
   public boolean matchingQualifier(final byte [] qualifier, int offset, int length) {
-    return Bytes.compareTo(qualifier, offset, length,
-        this.bytes, getQualifierOffset(), getQualifierLength()) == 0;
+    return Bytes.equals(qualifier, offset, length,
+        this.bytes, getQualifierOffset(), getQualifierLength());
   }
 
   public boolean matchingQualifier(final KeyValue other) {
@@ -1121,8 +1119,8 @@ public class KeyValue implements Writabl
   }
 
   public boolean matchingRow(final byte[] row, int offset, int length) {
-    return Bytes.compareTo(row, offset, length,
-        this.bytes, getRowOffset(), getRowLength()) == 0;
+    return Bytes.equals(row, offset, length,
+        this.bytes, getRowOffset(), getRowLength());
   }
 
   public boolean matchingRow(KeyValue other) {
@@ -1139,7 +1137,7 @@ public class KeyValue implements Writabl
     int o = getFamilyOffset(rl);
     int fl = getFamilyLength(o);
     int l = fl + getQualifierLength(rl,fl);
-    return Bytes.compareTo(column, 0, column.length, this.bytes, o, l) == 0;
+    return Bytes.equals(column, 0, column.length, this.bytes, o, l);
   }
 
   /**
@@ -1153,8 +1151,7 @@ public class KeyValue implements Writabl
     int o = getFamilyOffset(rl);
     int fl = getFamilyLength(o);
     int ql = getQualifierLength(rl,fl);
-    if (Bytes.compareTo(family, 0, family.length, this.bytes, o, family.length)
-        != 0) {
+    if (!Bytes.equals(family, 0, family.length, this.bytes, o, family.length)) {
       return false;
     }
     if (qualifier == null || qualifier.length == 0) {
@@ -1163,8 +1160,8 @@ public class KeyValue implements Writabl
       }
       return false;
     }
-    return Bytes.compareTo(qualifier, 0, qualifier.length,
-        this.bytes, o + fl, ql) == 0;
+    return Bytes.equals(qualifier, 0, qualifier.length,
+        this.bytes, o + fl, ql);
   }
 
   /**
@@ -1459,7 +1456,7 @@ public class KeyValue implements Writabl
       return getRawComparator().compareRows(left, loffset, llength,
         right, roffset, rlength);
     }
-
+    
     public int compareColumns(final KeyValue left, final byte [] right,
         final int roffset, final int rlength, final int rfamilyoffset) {
       int offset = left.getFamilyOffset();
@@ -1505,7 +1502,8 @@ public class KeyValue implements Writabl
      * @return True if rows match.
      */
     public boolean matchingRows(final KeyValue left, final byte [] right) {
-      return compareRows(left, right) == 0;
+      return Bytes.equals(left.getBuffer(), left.getRowOffset(), left.getRowLength(),
+          right, 0, right.length);
     }
 
     /**
@@ -1530,18 +1528,15 @@ public class KeyValue implements Writabl
     public boolean matchingRows(final KeyValue left, final short lrowlength,
         final KeyValue right, final short rrowlength) {
       return lrowlength == rrowlength &&
-        compareRows(left, lrowlength, right, rrowlength) == 0;
+          Bytes.equals(left.getBuffer(), left.getRowOffset(), lrowlength,
+              right.getBuffer(), right.getRowOffset(), rrowlength);
     }
 
     public boolean matchingRows(final byte [] left, final int loffset,
         final int llength,
         final byte [] right, final int roffset, final int rlength) {
-      int compare = compareRows(left, loffset, llength,
+      return Bytes.equals(left, loffset, llength,
           right, roffset, rlength);
-      if (compare != 0) {
-        return false;
-      }
-      return true;
     }
 
     /**

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java?rev=1135319&r1=1135318&r2=1135319&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java Mon Jun 13 22:15:11 2011
@@ -113,8 +113,8 @@ public class MetaReader {
     }
     // Compare the prefix of regionName.  If it matches META_REGION_PREFIX prefix,
     // then this is region from .META. table.
-    return Bytes.compareTo(regionName, 0, META_REGION_PREFIX.length,
-      META_REGION_PREFIX, 0, META_REGION_PREFIX.length) == 0;
+    return Bytes.equals(regionName, 0, META_REGION_PREFIX.length,
+      META_REGION_PREFIX, 0, META_REGION_PREFIX.length);
   }
 
   /**

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java?rev=1135319&r1=1135318&r2=1135319&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java Mon Jun 13 22:15:11 2011
@@ -729,7 +729,7 @@ public class HConnectionManager {
                   HConstants.REGIONINFO_QUALIFIER));
           if (info == null) return true;
           HTableDescriptor desc = info.getTableDesc();
-          if (Bytes.compareTo(desc.getName(), tableName) == 0) {
+          if (Bytes.equals(desc.getName(), tableName)) {
             result = desc;
             return false;
           }

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java?rev=1135319&r1=1135318&r2=1135319&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java Mon Jun 13 22:15:11 2011
@@ -1995,7 +1995,7 @@ public class HFile {
                     "\n\tfilename -> " + file +
                     "\n\tkeyvalue -> " + Bytes.toStringBinary(kv.getKey()));
               }
-              if (pkv != null && Bytes.compareTo(pkv.getFamily(), kv.getFamily()) != 0) {
+              if (pkv != null && !Bytes.equals(pkv.getFamily(), kv.getFamily())) {
                 System.err.println("WARNING, previous kv has different family" +
                     " compared to current key\n\tfilename -> " + file +
                     "\n\tprevious -> " +  Bytes.toStringBinary(pkv.getKey()) +
@@ -2017,17 +2017,17 @@ public class HFile {
           System.out.println("Fileinfo:");
           for (Map.Entry<byte[], byte[]> e : fileInfo.entrySet()) {
             System.out.print(Bytes.toString(e.getKey()) + " = " );
-            if (Bytes.compareTo(e.getKey(), Bytes.toBytes("MAX_SEQ_ID_KEY"))==0) {
+            if (Bytes.equals(e.getKey(), Bytes.toBytes("MAX_SEQ_ID_KEY"))) {
               long seqid = Bytes.toLong(e.getValue());
               System.out.println(seqid);
-            } else if (Bytes.compareTo(e.getKey(),
-                Bytes.toBytes("TIMERANGE")) == 0) {
+            } else if (Bytes.equals(e.getKey(),
+                Bytes.toBytes("TIMERANGE"))) {
               TimeRangeTracker timeRangeTracker = new TimeRangeTracker();
               Writables.copyWritable(e.getValue(), timeRangeTracker);
               System.out.println(timeRangeTracker.getMinimumTimestamp() +
                   "...." + timeRangeTracker.getMaximumTimestamp());
-            } else if (Bytes.compareTo(e.getKey(), FileInfo.AVG_KEY_LEN) == 0 ||
-                Bytes.compareTo(e.getKey(), FileInfo.AVG_VALUE_LEN) == 0) {
+            } else if (Bytes.equals(e.getKey(), FileInfo.AVG_KEY_LEN) ||
+                Bytes.equals(e.getKey(), FileInfo.AVG_VALUE_LEN)) {
               System.out.println(Bytes.toInt(e.getValue()));
             } else {
               System.out.println(Bytes.toStringBinary(e.getValue()));

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java?rev=1135319&r1=1135318&r2=1135319&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java Mon Jun 13 22:15:11 2011
@@ -1756,7 +1756,7 @@ public class HRegion implements HeapSize
     if (!isPut && !(w instanceof Delete))
       throw new DoNotRetryIOException("Action must be Put or Delete");
     Row r = (Row)w;
-    if (Bytes.compareTo(row, r.getRow()) != 0) {
+    if (!Bytes.equals(row, r.getRow())) {
       throw new DoNotRetryIOException("Action's getRow must match the passed row");
     }
 

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java?rev=1135319&r1=1135318&r2=1135319&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java Mon Jun 13 22:15:11 2011
@@ -76,8 +76,8 @@ public class ScanDeleteTracker implement
 
       if (deleteBuffer != null && type < deleteType) {
         // same column, so ignore less specific delete
-        if (Bytes.compareTo(deleteBuffer, deleteOffset, deleteLength,
-            buffer, qualifierOffset, qualifierLength) == 0){
+        if (Bytes.equals(deleteBuffer, deleteOffset, deleteLength,
+            buffer, qualifierOffset, qualifierLength)){
           return;
         }
       }

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/Bytes.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/Bytes.java?rev=1135319&r1=1135318&r2=1135319&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/Bytes.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/Bytes.java Mon Jun 13 22:15:11 2011
@@ -943,6 +943,12 @@ public class Bytes {
    */
   public static int compareTo(byte[] buffer1, int offset1, int length1,
       byte[] buffer2, int offset2, int length2) {
+    // Short circuit equal case
+    if (buffer1 == buffer2 &&
+        offset1 == offset2 &&
+        length1 == length2) {
+      return 0;
+    }
     // Bring WritableComparator code local
     int end1 = offset1 + length1;
     int end2 = offset2 + length2;
@@ -964,12 +970,44 @@ public class Bytes {
   public static boolean equals(final byte [] left, final byte [] right) {
     // Could use Arrays.equals?
     //noinspection SimplifiableConditionalExpression
-    if (left == null && right == null) {
+    if (left == right) return true;
+    if (left == null || right == null) return false;
+    if (left.length != right.length) return false;
+    if (left.length == 0) return true;
+    
+    // Since we're often comparing adjacent sorted data,
+    // it's usual to have equal arrays except for the very last byte
+    // so check that first
+    if (left[left.length - 1] != right[right.length - 1]) return false;
+
+    return compareTo(left, right) == 0;
+  }
+  
+  public static boolean equals(final byte[] left, int leftOffset, int leftLen,
+                               final byte[] right, int rightOffset, int rightLen) {
+    // short circuit case
+    if (left == right &&
+        leftOffset == rightOffset &&
+        leftLen == rightLen) {
       return true;
     }
-    return (left == null || right == null || (left.length != right.length)
-            ? false : compareTo(left, right) == 0);
+    // different lengths fast check
+    if (leftLen != rightLen) {
+      return false;
+    }
+    if (leftLen == 0) {
+      return true;
+    }
+    
+    // Since we're often comparing adjacent sorted data,
+    // it's usual to have equal arrays except for the very last byte
+    // so check that first
+    if (left[leftOffset + leftLen - 1] != right[rightOffset + rightLen - 1]) return false;
+
+    return compareTo(left, leftOffset, leftLen,
+                     right, rightOffset, rightLen) == 0;
   }
+  
 
   /**
    * Return true if the byte array on the right is a prefix of the byte