commit d50c6caa06c0dd85bfea59917f19d0de342b0abd Author: Todd Lipcon Date: Thu May 26 20:39:52 2011 -0700 HBASE-3928. some bytes optimzations diff --git src/main/java/org/apache/hadoop/hbase/KeyValue.java src/main/java/org/apache/hadoop/hbase/KeyValue.java index 7033800..269a895 100644 --- src/main/java/org/apache/hadoop/hbase/KeyValue.java +++ src/main/java/org/apache/hadoop/hbase/KeyValue.java @@ -529,10 +529,8 @@ public class KeyValue implements Writable, HeapSize { 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 Writable, HeapSize { * @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 Writable, HeapSize { 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 Writable, HeapSize { } 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 Writable, HeapSize { } 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 Writable, HeapSize { 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 Writable, HeapSize { 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 Writable, HeapSize { } 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 Writable, HeapSize { 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 Writable, HeapSize { * @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 Writable, HeapSize { 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; } /** diff --git src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java index eb57197..950f20d 100644 --- src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java +++ src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java @@ -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); } /** diff --git src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java index 94ee1a0..2c408d8 100644 --- src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java +++ src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java @@ -730,7 +730,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; } diff --git src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java index cb52fac..3c7ad88 100644 --- src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java +++ src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java @@ -2004,7 +2004,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()) + @@ -2026,17 +2026,17 @@ public class HFile { System.out.println("Fileinfo:"); for (Map.Entry 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())); diff --git src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index e5bd154..ff7f863 100644 --- src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -1756,7 +1756,7 @@ public class HRegion implements HeapSize { // , Writable{ 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"); } diff --git src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java index 6c4580e..8c03a14 100644 --- src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java +++ src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java @@ -76,8 +76,8 @@ public class ScanDeleteTracker implements DeleteTracker { 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; } } diff --git src/main/java/org/apache/hadoop/hbase/util/Bytes.java src/main/java/org/apache/hadoop/hbase/util/Bytes.java index 3f979a6..39831ec 100644 --- src/main/java/org/apache/hadoop/hbase/util/Bytes.java +++ src/main/java/org/apache/hadoop/hbase/util/Bytes.java @@ -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