diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java index 11fe5dd..d2d5fe2 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java @@ -465,9 +465,9 @@ public final class CellUtil { public static boolean matchingRow(final Cell left, final byte[] buf, final int offset, final int length) { if (left instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getRowByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) left).getRowByteBuffer(), ((ByteBufferedCell) left).getRowPositionInByteBuffer(), left.getRowLength(), buf, offset, - length) == 0; + length); } return Bytes.equals(left.getRowArray(), left.getRowOffset(), left.getRowLength(), buf, offset, length); @@ -476,22 +476,21 @@ public final class CellUtil { public static boolean matchingFamily(final Cell left, final Cell right) { byte lfamlength = left.getFamilyLength(); byte rfamlength = right.getFamilyLength(); - if (lfamlength != rfamlength) return false; if (left instanceof ByteBufferedCell && right instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getFamilyByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) left).getFamilyByteBuffer(), ((ByteBufferedCell) left).getFamilyPositionInByteBuffer(), lfamlength, ((ByteBufferedCell) right).getFamilyByteBuffer(), - ((ByteBufferedCell) right).getFamilyPositionInByteBuffer(), rfamlength) == 0; + ((ByteBufferedCell) right).getFamilyPositionInByteBuffer(), rfamlength); } if (left instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getFamilyByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) left).getFamilyByteBuffer(), ((ByteBufferedCell) left).getFamilyPositionInByteBuffer(), lfamlength, - right.getFamilyArray(), right.getFamilyOffset(), rfamlength) == 0; + right.getFamilyArray(), right.getFamilyOffset(), rfamlength); } if (right instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) right).getFamilyByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) right).getFamilyByteBuffer(), ((ByteBufferedCell) right).getFamilyPositionInByteBuffer(), rfamlength, - left.getFamilyArray(), left.getFamilyOffset(), lfamlength) == 0; + left.getFamilyArray(), left.getFamilyOffset(), lfamlength); } return Bytes.equals(left.getFamilyArray(), left.getFamilyOffset(), left.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, final int length) { if (left instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getFamilyByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) left).getFamilyByteBuffer(), ((ByteBufferedCell) left).getFamilyPositionInByteBuffer(), left.getFamilyLength(), buf, - offset, length) == 0; + offset, length); } return Bytes.equals(left.getFamilyArray(), left.getFamilyOffset(), left.getFamilyLength(), buf, offset, length); @@ -518,22 +517,21 @@ public final class CellUtil { public static boolean matchingQualifier(final Cell left, final Cell right) { int lqlength = left.getQualifierLength(); int rqlength = right.getQualifierLength(); - if (lqlength != rqlength) return false; if (left instanceof ByteBufferedCell && right instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getQualifierByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) left).getQualifierByteBuffer(), ((ByteBufferedCell) left).getQualifierPositionInByteBuffer(), lqlength, ((ByteBufferedCell) right).getQualifierByteBuffer(), - ((ByteBufferedCell) right).getQualifierPositionInByteBuffer(), rqlength) == 0; + ((ByteBufferedCell) right).getQualifierPositionInByteBuffer(), rqlength); } if (left instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getQualifierByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) left).getQualifierByteBuffer(), ((ByteBufferedCell) left).getQualifierPositionInByteBuffer(), lqlength, - right.getQualifierArray(), right.getQualifierOffset(), rqlength) == 0; + right.getQualifierArray(), right.getQualifierOffset(), rqlength); } if (right instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) right).getQualifierByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) right).getQualifierByteBuffer(), ((ByteBufferedCell) right).getQualifierPositionInByteBuffer(), rqlength, - left.getQualifierArray(), left.getQualifierOffset(), lqlength) == 0; + left.getQualifierArray(), left.getQualifierOffset(), lqlength); } return Bytes.equals(left.getQualifierArray(), left.getQualifierOffset(), left.getQualifierLength(), right.getQualifierArray(), right.getQualifierOffset(), @@ -569,9 +567,9 @@ public final class CellUtil { return left.getQualifierLength() == 0; } if (left instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getQualifierByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) left).getQualifierByteBuffer(), ((ByteBufferedCell) left).getQualifierPositionInByteBuffer(), left.getQualifierLength(), - buf, offset, length) == 0; + buf, offset, length); } return Bytes.equals(left.getQualifierArray(), left.getQualifierOffset(), left.getQualifierLength(), buf, offset, length); @@ -599,22 +597,21 @@ public final class CellUtil { public static boolean matchingValue(final Cell left, final Cell right) { int lvlength = left.getValueLength(); int rvlength = right.getValueLength(); - if (lvlength != rvlength) return false; if (left instanceof ByteBufferedCell && right instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getValueByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) left).getValueByteBuffer(), ((ByteBufferedCell) left).getValuePositionInByteBuffer(), lvlength, ((ByteBufferedCell) right).getValueByteBuffer(), - ((ByteBufferedCell) right).getValuePositionInByteBuffer(), rvlength) == 0; + ((ByteBufferedCell) right).getValuePositionInByteBuffer(), rvlength); } if (left instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getValueByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) left).getValueByteBuffer(), ((ByteBufferedCell) left).getValuePositionInByteBuffer(), lvlength, - right.getValueArray(), right.getValueOffset(), rvlength) == 0; + right.getValueArray(), right.getValueOffset(), rvlength); } if (right instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) right).getValueByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) right).getValueByteBuffer(), ((ByteBufferedCell) right).getValuePositionInByteBuffer(), rvlength, - left.getValueArray(), left.getValueOffset(), lvlength) == 0; + left.getValueArray(), left.getValueOffset(), lvlength); } return Bytes.equals(left.getValueArray(), left.getValueOffset(), lvlength, right.getValueArray(), right.getValueOffset(), rvlength); @@ -1124,20 +1121,20 @@ public final class CellUtil { short rrowlength = right.getRowLength(); if (lrowlength != rrowlength) return false; if (left instanceof ByteBufferedCell && right instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getRowByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) left).getRowByteBuffer(), ((ByteBufferedCell) left).getRowPositionInByteBuffer(), lrowlength, ((ByteBufferedCell) right).getRowByteBuffer(), - ((ByteBufferedCell) right).getRowPositionInByteBuffer(), rrowlength) == 0; + ((ByteBufferedCell) right).getRowPositionInByteBuffer(), rrowlength); } if (left instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) left).getRowByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) left).getRowByteBuffer(), ((ByteBufferedCell) left).getRowPositionInByteBuffer(), lrowlength, right.getRowArray(), - right.getRowOffset(), rrowlength) == 0; + right.getRowOffset(), rrowlength); } if (right instanceof ByteBufferedCell) { - return ByteBufferUtils.compareTo(((ByteBufferedCell) right).getRowByteBuffer(), + return ByteBufferUtils.equals(((ByteBufferedCell) right).getRowByteBuffer(), ((ByteBufferedCell) right).getRowPositionInByteBuffer(), rrowlength, left.getRowArray(), - left.getRowOffset(), lrowlength) == 0; + left.getRowOffset(), lrowlength); } return Bytes.equals(left.getRowArray(), left.getRowOffset(), left.getRowLength(), right.getRowArray(), right.getRowOffset(), right.getRowLength()); diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/OffheapKeyValue.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/OffheapKeyValue.java index 8f51d4d..13e7ac7 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/OffheapKeyValue.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/OffheapKeyValue.java @@ -45,7 +45,7 @@ public class OffheapKeyValue extends ByteBufferedCell implements HeapSize, Clone // TODO : See if famLen can be cached or not? 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; public OffheapKeyValue(ByteBuffer buf, int offset, int length, boolean hasTags, long seqId) { diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java index 6990506..5290d5e 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java @@ -46,6 +46,7 @@ public final class ByteBufferUtils { public final static int VALUE_MASK = 0x7f; public final static int NEXT_BIT_SHIFT = 7; public final static int NEXT_BIT_MASK = 1 << 7; + private static final boolean UNSAFE_AVAIL = UnsafeAccess.isAvailable(); private ByteBufferUtils() { } @@ -388,7 +389,7 @@ public final class ByteBufferUtils { if (in.hasArray() && out.hasArray()) { System.arraycopy(in.array(), sourceOffset + in.arrayOffset(), out.array(), out.arrayOffset() + destinationOffset, length); - } else if (UnsafeAccess.isAvailable()) { + } else if (UNSAFE_AVAIL) { UnsafeAccess.copy(in, sourceOffset, out, destinationOffset, length); } else { for (int i = 0; i < length; ++i) { @@ -413,7 +414,7 @@ public final class ByteBufferUtils { if (in.hasArray() && out.hasArray()) { System.arraycopy(in.array(), sourceOffset + in.arrayOffset(), out.array(), out.position() + out.arrayOffset(), length); - } else if (UnsafeAccess.isAvailable()) { + } else if (UNSAFE_AVAIL) { UnsafeAccess.copy(in, sourceOffset, out, out.position(), length); } else { int destOffset = out.position(); @@ -542,8 +543,16 @@ public final class ByteBufferUtils { 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) { - if (UnsafeAccess.isAvailable()) { + if (UNSAFE_AVAIL) { long offset1Adj, offset2Adj; Object refObj1 = null, refObj2 = null; if (buf1.isDirect()) { @@ -572,8 +581,16 @@ public final class ByteBufferUtils { 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) { - if (UnsafeAccess.isAvailable()) { + if (UNSAFE_AVAIL) { long offset1Adj; Object refObj1 = null; if (buf1.isDirect()) { @@ -686,7 +703,7 @@ public final class ByteBufferUtils { * @return short value at offset */ public static short toShort(ByteBuffer buffer, int offset) { - if (UnsafeAccess.isAvailable()) { + if (UNSAFE_AVAIL) { return UnsafeAccess.toShort(buffer, offset); } else { return buffer.getShort(offset); @@ -700,7 +717,7 @@ public final class ByteBufferUtils { * @return int value at offset */ public static int toInt(ByteBuffer buffer, int offset) { - if (UnsafeAccess.isAvailable()) { + if (UNSAFE_AVAIL) { return UnsafeAccess.toInt(buffer, offset); } else { return buffer.getInt(offset); @@ -714,7 +731,7 @@ public final class ByteBufferUtils { * @return long value at offset */ public static long toLong(ByteBuffer buffer, int offset) { - if (UnsafeAccess.isAvailable()) { + if (UNSAFE_AVAIL) { return UnsafeAccess.toLong(buffer, offset); } else { return buffer.getLong(offset); @@ -728,7 +745,7 @@ public final class ByteBufferUtils { * @param val int to write out */ public static void putInt(ByteBuffer buffer, int val) { - if (UnsafeAccess.isAvailable()) { + if (UNSAFE_AVAIL) { int newPos = UnsafeAccess.putInt(buffer, buffer.position(), val); buffer.position(newPos); } else { @@ -771,7 +788,7 @@ public final class ByteBufferUtils { * @param val short to write out */ public static void putShort(ByteBuffer buffer, short val) { - if (UnsafeAccess.isAvailable()) { + if (UNSAFE_AVAIL) { int newPos = UnsafeAccess.putShort(buffer, buffer.position(), val); buffer.position(newPos); } else { @@ -786,7 +803,7 @@ public final class ByteBufferUtils { * @param val long to write out */ public static void putLong(ByteBuffer buffer, long val) { - if (UnsafeAccess.isAvailable()) { + if (UNSAFE_AVAIL) { int newPos = UnsafeAccess.putLong(buffer, buffer.position(), val); buffer.position(newPos); } else { @@ -806,7 +823,7 @@ public final class ByteBufferUtils { System.arraycopy(in, inOffset, out.array(), out.arrayOffset() + out.position(), length); // Move the position in out by length out.position(out.position() + length); - } else if (UnsafeAccess.isAvailable()) { + } else if (UNSAFE_AVAIL) { UnsafeAccess.copy(in, inOffset, out, out.position(), length); // Move the position in out by length out.position(out.position() + length); @@ -828,7 +845,7 @@ public final class ByteBufferUtils { int destinationOffset, int length) { if (in.hasArray()) { 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); } else { for (int i = 0; i < length; i++) {