HBASE-14395 Short circuit last byte check in CellUtil#matchingXXX methods for ByteBufferedCells.

This commit is contained in:
anoopsjohn 2015-09-11 10:29:30 +05:30
parent 411b516f51
commit ae3176b9c0
3 changed files with 60 additions and 46 deletions

View File

@ -465,9 +465,9 @@ public final class CellUtil {
public static boolean matchingRow(final Cell left, final byte[] buf, final int offset, public static boolean matchingRow(final Cell left, final byte[] buf, final int offset,
final int length) { final int length) {
if (left instanceof ByteBufferedCell) { if (left instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getRowByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) left).getRowByteBuffer(),
((ByteBufferedCell) left).getRowPositionInByteBuffer(), left.getRowLength(), buf, offset, ((ByteBufferedCell) left).getRowPositionInByteBuffer(), left.getRowLength(), buf, offset,
length) == 0; length);
} }
return Bytes.equals(left.getRowArray(), left.getRowOffset(), left.getRowLength(), buf, offset, return Bytes.equals(left.getRowArray(), left.getRowOffset(), left.getRowLength(), buf, offset,
length); length);
@ -476,22 +476,21 @@ public final class CellUtil {
public static boolean matchingFamily(final Cell left, final Cell right) { public static boolean matchingFamily(final Cell left, final Cell right) {
byte lfamlength = left.getFamilyLength(); byte lfamlength = left.getFamilyLength();
byte rfamlength = right.getFamilyLength(); byte rfamlength = right.getFamilyLength();
if (lfamlength != rfamlength) return false;
if (left instanceof ByteBufferedCell && right instanceof ByteBufferedCell) { if (left instanceof ByteBufferedCell && right instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getFamilyByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) left).getFamilyByteBuffer(),
((ByteBufferedCell) left).getFamilyPositionInByteBuffer(), lfamlength, ((ByteBufferedCell) left).getFamilyPositionInByteBuffer(), lfamlength,
((ByteBufferedCell) right).getFamilyByteBuffer(), ((ByteBufferedCell) right).getFamilyByteBuffer(),
((ByteBufferedCell) right).getFamilyPositionInByteBuffer(), rfamlength) == 0; ((ByteBufferedCell) right).getFamilyPositionInByteBuffer(), rfamlength);
} }
if (left instanceof ByteBufferedCell) { if (left instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getFamilyByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) left).getFamilyByteBuffer(),
((ByteBufferedCell) left).getFamilyPositionInByteBuffer(), lfamlength, ((ByteBufferedCell) left).getFamilyPositionInByteBuffer(), lfamlength,
right.getFamilyArray(), right.getFamilyOffset(), rfamlength) == 0; right.getFamilyArray(), right.getFamilyOffset(), rfamlength);
} }
if (right instanceof ByteBufferedCell) { if (right instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) right).getFamilyByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) right).getFamilyByteBuffer(),
((ByteBufferedCell) right).getFamilyPositionInByteBuffer(), rfamlength, ((ByteBufferedCell) right).getFamilyPositionInByteBuffer(), rfamlength,
left.getFamilyArray(), left.getFamilyOffset(), lfamlength) == 0; left.getFamilyArray(), left.getFamilyOffset(), lfamlength);
} }
return Bytes.equals(left.getFamilyArray(), left.getFamilyOffset(), left.getFamilyLength(), return Bytes.equals(left.getFamilyArray(), left.getFamilyOffset(), left.getFamilyLength(),
right.getFamilyArray(), right.getFamilyOffset(), right.getFamilyLength()); right.getFamilyArray(), right.getFamilyOffset(), right.getFamilyLength());
@ -507,9 +506,9 @@ public final class CellUtil {
public static boolean matchingFamily(final Cell left, final byte[] buf, final int offset, public static boolean matchingFamily(final Cell left, final byte[] buf, final int offset,
final int length) { final int length) {
if (left instanceof ByteBufferedCell) { if (left instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getFamilyByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) left).getFamilyByteBuffer(),
((ByteBufferedCell) left).getFamilyPositionInByteBuffer(), left.getFamilyLength(), buf, ((ByteBufferedCell) left).getFamilyPositionInByteBuffer(), left.getFamilyLength(), buf,
offset, length) == 0; offset, length);
} }
return Bytes.equals(left.getFamilyArray(), left.getFamilyOffset(), left.getFamilyLength(), buf, return Bytes.equals(left.getFamilyArray(), left.getFamilyOffset(), left.getFamilyLength(), buf,
offset, length); offset, length);
@ -518,22 +517,21 @@ public final class CellUtil {
public static boolean matchingQualifier(final Cell left, final Cell right) { public static boolean matchingQualifier(final Cell left, final Cell right) {
int lqlength = left.getQualifierLength(); int lqlength = left.getQualifierLength();
int rqlength = right.getQualifierLength(); int rqlength = right.getQualifierLength();
if (lqlength != rqlength) return false;
if (left instanceof ByteBufferedCell && right instanceof ByteBufferedCell) { if (left instanceof ByteBufferedCell && right instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getQualifierByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) left).getQualifierByteBuffer(),
((ByteBufferedCell) left).getQualifierPositionInByteBuffer(), lqlength, ((ByteBufferedCell) left).getQualifierPositionInByteBuffer(), lqlength,
((ByteBufferedCell) right).getQualifierByteBuffer(), ((ByteBufferedCell) right).getQualifierByteBuffer(),
((ByteBufferedCell) right).getQualifierPositionInByteBuffer(), rqlength) == 0; ((ByteBufferedCell) right).getQualifierPositionInByteBuffer(), rqlength);
} }
if (left instanceof ByteBufferedCell) { if (left instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getQualifierByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) left).getQualifierByteBuffer(),
((ByteBufferedCell) left).getQualifierPositionInByteBuffer(), lqlength, ((ByteBufferedCell) left).getQualifierPositionInByteBuffer(), lqlength,
right.getQualifierArray(), right.getQualifierOffset(), rqlength) == 0; right.getQualifierArray(), right.getQualifierOffset(), rqlength);
} }
if (right instanceof ByteBufferedCell) { if (right instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) right).getQualifierByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) right).getQualifierByteBuffer(),
((ByteBufferedCell) right).getQualifierPositionInByteBuffer(), rqlength, ((ByteBufferedCell) right).getQualifierPositionInByteBuffer(), rqlength,
left.getQualifierArray(), left.getQualifierOffset(), lqlength) == 0; left.getQualifierArray(), left.getQualifierOffset(), lqlength);
} }
return Bytes.equals(left.getQualifierArray(), left.getQualifierOffset(), return Bytes.equals(left.getQualifierArray(), left.getQualifierOffset(),
left.getQualifierLength(), right.getQualifierArray(), right.getQualifierOffset(), left.getQualifierLength(), right.getQualifierArray(), right.getQualifierOffset(),
@ -569,9 +567,9 @@ public final class CellUtil {
return left.getQualifierLength() == 0; return left.getQualifierLength() == 0;
} }
if (left instanceof ByteBufferedCell) { if (left instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getQualifierByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) left).getQualifierByteBuffer(),
((ByteBufferedCell) left).getQualifierPositionInByteBuffer(), left.getQualifierLength(), ((ByteBufferedCell) left).getQualifierPositionInByteBuffer(), left.getQualifierLength(),
buf, offset, length) == 0; buf, offset, length);
} }
return Bytes.equals(left.getQualifierArray(), left.getQualifierOffset(), return Bytes.equals(left.getQualifierArray(), left.getQualifierOffset(),
left.getQualifierLength(), buf, offset, length); left.getQualifierLength(), buf, offset, length);
@ -599,22 +597,21 @@ public final class CellUtil {
public static boolean matchingValue(final Cell left, final Cell right) { public static boolean matchingValue(final Cell left, final Cell right) {
int lvlength = left.getValueLength(); int lvlength = left.getValueLength();
int rvlength = right.getValueLength(); int rvlength = right.getValueLength();
if (lvlength != rvlength) return false;
if (left instanceof ByteBufferedCell && right instanceof ByteBufferedCell) { if (left instanceof ByteBufferedCell && right instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getValueByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) left).getValueByteBuffer(),
((ByteBufferedCell) left).getValuePositionInByteBuffer(), lvlength, ((ByteBufferedCell) left).getValuePositionInByteBuffer(), lvlength,
((ByteBufferedCell) right).getValueByteBuffer(), ((ByteBufferedCell) right).getValueByteBuffer(),
((ByteBufferedCell) right).getValuePositionInByteBuffer(), rvlength) == 0; ((ByteBufferedCell) right).getValuePositionInByteBuffer(), rvlength);
} }
if (left instanceof ByteBufferedCell) { if (left instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getValueByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) left).getValueByteBuffer(),
((ByteBufferedCell) left).getValuePositionInByteBuffer(), lvlength, ((ByteBufferedCell) left).getValuePositionInByteBuffer(), lvlength,
right.getValueArray(), right.getValueOffset(), rvlength) == 0; right.getValueArray(), right.getValueOffset(), rvlength);
} }
if (right instanceof ByteBufferedCell) { if (right instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) right).getValueByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) right).getValueByteBuffer(),
((ByteBufferedCell) right).getValuePositionInByteBuffer(), rvlength, ((ByteBufferedCell) right).getValuePositionInByteBuffer(), rvlength,
left.getValueArray(), left.getValueOffset(), lvlength) == 0; left.getValueArray(), left.getValueOffset(), lvlength);
} }
return Bytes.equals(left.getValueArray(), left.getValueOffset(), lvlength, return Bytes.equals(left.getValueArray(), left.getValueOffset(), lvlength,
right.getValueArray(), right.getValueOffset(), rvlength); right.getValueArray(), right.getValueOffset(), rvlength);
@ -1124,20 +1121,20 @@ public final class CellUtil {
short rrowlength = right.getRowLength(); short rrowlength = right.getRowLength();
if (lrowlength != rrowlength) return false; if (lrowlength != rrowlength) return false;
if (left instanceof ByteBufferedCell && right instanceof ByteBufferedCell) { if (left instanceof ByteBufferedCell && right instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getRowByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) left).getRowByteBuffer(),
((ByteBufferedCell) left).getRowPositionInByteBuffer(), lrowlength, ((ByteBufferedCell) left).getRowPositionInByteBuffer(), lrowlength,
((ByteBufferedCell) right).getRowByteBuffer(), ((ByteBufferedCell) right).getRowByteBuffer(),
((ByteBufferedCell) right).getRowPositionInByteBuffer(), rrowlength) == 0; ((ByteBufferedCell) right).getRowPositionInByteBuffer(), rrowlength);
} }
if (left instanceof ByteBufferedCell) { if (left instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getRowByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) left).getRowByteBuffer(),
((ByteBufferedCell) left).getRowPositionInByteBuffer(), lrowlength, right.getRowArray(), ((ByteBufferedCell) left).getRowPositionInByteBuffer(), lrowlength, right.getRowArray(),
right.getRowOffset(), rrowlength) == 0; right.getRowOffset(), rrowlength);
} }
if (right instanceof ByteBufferedCell) { if (right instanceof ByteBufferedCell) {
return ByteBufferUtils.compareTo(((ByteBufferedCell) right).getRowByteBuffer(), return ByteBufferUtils.equals(((ByteBufferedCell) right).getRowByteBuffer(),
((ByteBufferedCell) right).getRowPositionInByteBuffer(), rrowlength, left.getRowArray(), ((ByteBufferedCell) right).getRowPositionInByteBuffer(), rrowlength, left.getRowArray(),
left.getRowOffset(), lrowlength) == 0; left.getRowOffset(), lrowlength);
} }
return Bytes.equals(left.getRowArray(), left.getRowOffset(), left.getRowLength(), return Bytes.equals(left.getRowArray(), left.getRowOffset(), left.getRowLength(),
right.getRowArray(), right.getRowOffset(), right.getRowLength()); right.getRowArray(), right.getRowOffset(), right.getRowLength());

View File

@ -45,7 +45,7 @@ public class OffheapKeyValue extends ByteBufferedCell implements HeapSize, Clone
// TODO : See if famLen can be cached or not? // TODO : See if famLen can be cached or not?
private static final int FIXED_HEAP_SIZE_OVERHEAD = ClassSize.OBJECT + ClassSize.REFERENCE private static final int FIXED_HEAP_SIZE_OVERHEAD = ClassSize.OBJECT + ClassSize.REFERENCE
+ ClassSize.align(ClassSize.BYTE_BUFFER) + (3 * Bytes.SIZEOF_INT) + Bytes.SIZEOF_SHORT + (3 * Bytes.SIZEOF_INT) + Bytes.SIZEOF_SHORT
+ Bytes.SIZEOF_BOOLEAN + Bytes.SIZEOF_LONG; + Bytes.SIZEOF_BOOLEAN + Bytes.SIZEOF_LONG;
public OffheapKeyValue(ByteBuffer buf, int offset, int length, boolean hasTags, long seqId) { public OffheapKeyValue(ByteBuffer buf, int offset, int length, boolean hasTags, long seqId) {

View File

@ -46,6 +46,7 @@ public final class ByteBufferUtils {
public final static int VALUE_MASK = 0x7f; public final static int VALUE_MASK = 0x7f;
public final static int NEXT_BIT_SHIFT = 7; public final static int NEXT_BIT_SHIFT = 7;
public final static int NEXT_BIT_MASK = 1 << 7; public final static int NEXT_BIT_MASK = 1 << 7;
private static final boolean UNSAFE_AVAIL = UnsafeAccess.isAvailable();
private ByteBufferUtils() { private ByteBufferUtils() {
} }
@ -388,7 +389,7 @@ public final class ByteBufferUtils {
if (in.hasArray() && out.hasArray()) { if (in.hasArray() && out.hasArray()) {
System.arraycopy(in.array(), sourceOffset + in.arrayOffset(), out.array(), out.arrayOffset() System.arraycopy(in.array(), sourceOffset + in.arrayOffset(), out.array(), out.arrayOffset()
+ destinationOffset, length); + destinationOffset, length);
} else if (UnsafeAccess.isAvailable()) { } else if (UNSAFE_AVAIL) {
UnsafeAccess.copy(in, sourceOffset, out, destinationOffset, length); UnsafeAccess.copy(in, sourceOffset, out, destinationOffset, length);
} else { } else {
for (int i = 0; i < length; ++i) { for (int i = 0; i < length; ++i) {
@ -413,7 +414,7 @@ public final class ByteBufferUtils {
if (in.hasArray() && out.hasArray()) { if (in.hasArray() && out.hasArray()) {
System.arraycopy(in.array(), sourceOffset + in.arrayOffset(), out.array(), out.position() System.arraycopy(in.array(), sourceOffset + in.arrayOffset(), out.array(), out.position()
+ out.arrayOffset(), length); + out.arrayOffset(), length);
} else if (UnsafeAccess.isAvailable()) { } else if (UNSAFE_AVAIL) {
UnsafeAccess.copy(in, sourceOffset, out, out.position(), length); UnsafeAccess.copy(in, sourceOffset, out, out.position(), length);
} else { } else {
int destOffset = out.position(); int destOffset = out.position();
@ -542,8 +543,16 @@ public final class ByteBufferUtils {
return output; return output;
} }
public static boolean equals(ByteBuffer buf1, int o1, int l1, ByteBuffer buf2, int o2, int l2) {
// 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 (toByte(buf1, o1 + l1 - 1) != toByte(buf2, o2 + l2 - 1)) return false;
return compareTo(buf1, o1, l1, buf2, o2, l2) == 0;
}
public static int compareTo(ByteBuffer buf1, int o1, int l1, ByteBuffer buf2, int o2, int l2) { public static int compareTo(ByteBuffer buf1, int o1, int l1, ByteBuffer buf2, int o2, int l2) {
if (UnsafeAccess.isAvailable()) { if (UNSAFE_AVAIL) {
long offset1Adj, offset2Adj; long offset1Adj, offset2Adj;
Object refObj1 = null, refObj2 = null; Object refObj1 = null, refObj2 = null;
if (buf1.isDirect()) { if (buf1.isDirect()) {
@ -572,8 +581,16 @@ public final class ByteBufferUtils {
return l1 - l2; return l1 - l2;
} }
public static boolean equals(ByteBuffer buf1, int o1, int l1, byte[] buf2, int o2, int l2) {
// 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 (toByte(buf1, o1 + l1 - 1) != buf2[o2 + l2 - 1]) return false;
return compareTo(buf1, o1, l1, buf2, o2, l2) == 0;
}
public static int compareTo(ByteBuffer buf1, int o1, int l1, byte[] buf2, int o2, int l2) { public static int compareTo(ByteBuffer buf1, int o1, int l1, byte[] buf2, int o2, int l2) {
if (UnsafeAccess.isAvailable()) { if (UNSAFE_AVAIL) {
long offset1Adj; long offset1Adj;
Object refObj1 = null; Object refObj1 = null;
if (buf1.isDirect()) { if (buf1.isDirect()) {
@ -686,7 +703,7 @@ public final class ByteBufferUtils {
* @return short value at offset * @return short value at offset
*/ */
public static short toShort(ByteBuffer buffer, int offset) { public static short toShort(ByteBuffer buffer, int offset) {
if (UnsafeAccess.isAvailable()) { if (UNSAFE_AVAIL) {
return UnsafeAccess.toShort(buffer, offset); return UnsafeAccess.toShort(buffer, offset);
} else { } else {
return buffer.getShort(offset); return buffer.getShort(offset);
@ -700,7 +717,7 @@ public final class ByteBufferUtils {
* @return int value at offset * @return int value at offset
*/ */
public static int toInt(ByteBuffer buffer, int offset) { public static int toInt(ByteBuffer buffer, int offset) {
if (UnsafeAccess.isAvailable()) { if (UNSAFE_AVAIL) {
return UnsafeAccess.toInt(buffer, offset); return UnsafeAccess.toInt(buffer, offset);
} else { } else {
return buffer.getInt(offset); return buffer.getInt(offset);
@ -714,7 +731,7 @@ public final class ByteBufferUtils {
* @return long value at offset * @return long value at offset
*/ */
public static long toLong(ByteBuffer buffer, int offset) { public static long toLong(ByteBuffer buffer, int offset) {
if (UnsafeAccess.isAvailable()) { if (UNSAFE_AVAIL) {
return UnsafeAccess.toLong(buffer, offset); return UnsafeAccess.toLong(buffer, offset);
} else { } else {
return buffer.getLong(offset); return buffer.getLong(offset);
@ -728,7 +745,7 @@ public final class ByteBufferUtils {
* @param val int to write out * @param val int to write out
*/ */
public static void putInt(ByteBuffer buffer, int val) { public static void putInt(ByteBuffer buffer, int val) {
if (UnsafeAccess.isAvailable()) { if (UNSAFE_AVAIL) {
int newPos = UnsafeAccess.putInt(buffer, buffer.position(), val); int newPos = UnsafeAccess.putInt(buffer, buffer.position(), val);
buffer.position(newPos); buffer.position(newPos);
} else { } else {
@ -771,7 +788,7 @@ public final class ByteBufferUtils {
* @param val short to write out * @param val short to write out
*/ */
public static void putShort(ByteBuffer buffer, short val) { public static void putShort(ByteBuffer buffer, short val) {
if (UnsafeAccess.isAvailable()) { if (UNSAFE_AVAIL) {
int newPos = UnsafeAccess.putShort(buffer, buffer.position(), val); int newPos = UnsafeAccess.putShort(buffer, buffer.position(), val);
buffer.position(newPos); buffer.position(newPos);
} else { } else {
@ -786,7 +803,7 @@ public final class ByteBufferUtils {
* @param val long to write out * @param val long to write out
*/ */
public static void putLong(ByteBuffer buffer, long val) { public static void putLong(ByteBuffer buffer, long val) {
if (UnsafeAccess.isAvailable()) { if (UNSAFE_AVAIL) {
int newPos = UnsafeAccess.putLong(buffer, buffer.position(), val); int newPos = UnsafeAccess.putLong(buffer, buffer.position(), val);
buffer.position(newPos); buffer.position(newPos);
} else { } else {
@ -806,7 +823,7 @@ public final class ByteBufferUtils {
System.arraycopy(in, inOffset, out.array(), out.arrayOffset() + out.position(), length); System.arraycopy(in, inOffset, out.array(), out.arrayOffset() + out.position(), length);
// Move the position in out by length // Move the position in out by length
out.position(out.position() + length); out.position(out.position() + length);
} else if (UnsafeAccess.isAvailable()) { } else if (UNSAFE_AVAIL) {
UnsafeAccess.copy(in, inOffset, out, out.position(), length); UnsafeAccess.copy(in, inOffset, out, out.position(), length);
// Move the position in out by length // Move the position in out by length
out.position(out.position() + length); out.position(out.position() + length);
@ -828,7 +845,7 @@ public final class ByteBufferUtils {
int destinationOffset, int length) { int destinationOffset, int length) {
if (in.hasArray()) { if (in.hasArray()) {
System.arraycopy(in.array(), sourceOffset + in.arrayOffset(), out, destinationOffset, length); System.arraycopy(in.array(), sourceOffset + in.arrayOffset(), out, destinationOffset, length);
} else if (UnsafeAccess.isAvailable()) { } else if (UNSAFE_AVAIL) {
UnsafeAccess.copy(in, sourceOffset, out, destinationOffset, length); UnsafeAccess.copy(in, sourceOffset, out, destinationOffset, length);
} else { } else {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {