HBASE-3928 Some potential performance improvements to Bytes/KeyValue

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1135319 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Stack 2011-06-13 22:15:11 +00:00
parent 1e5deae9e9
commit ac2e192ad5
8 changed files with 74 additions and 40 deletions

View File

@ -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

View File

@ -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;
}
/**

View File

@ -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);
}
/**

View File

@ -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;
}

View File

@ -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()));

View File

@ -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");
}

View File

@ -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;
}
}

View File

@ -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