.../org/apache/hadoop/hbase/util/ByteBufferUtils.java | 12 +++++++++--- .../org/apache/hadoop/hbase/util/TestByteBufferUtils.java | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) 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 c491fe1..0653d1a 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 @@ -365,16 +365,22 @@ public final class ByteBufferUtils { /** * Copy one buffer's whole data to another. Write starts at the current position of 'out' buffer. - * Note : This will advance the position marker of {@code out} but not change the position maker - * for {@code in}. The position and limit of the {@code in} buffer to be set properly by caller. + * Note : This will advance the position marker of {@code out} and also change the position maker + * for {@code in}. * @param in source buffer * @param out destination buffer */ public static void copyFromBufferToBuffer(ByteBuffer in, ByteBuffer out) { - if (UNSAFE_AVAIL) { + if (in.hasArray() && out.hasArray()) { + int length = in.remaining(); + System.arraycopy(in.array(), in.arrayOffset(), out.array(), out.arrayOffset(), length); + out.position(out.position() + length); + in.position(in.limit()); + } else if (UNSAFE_AVAIL) { int length = in.remaining(); UnsafeAccess.copy(in, in.position(), out, out.position(), length); out.position(out.position() + length); + in.position(in.limit()); } else { out.put(in); } diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java index dfbc015..e94293c 100644 --- a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java @@ -375,6 +375,21 @@ public class TestByteBufferUtils { } @Test + public void testRelativeCopyFromBuffertoBuffer() { + ByteBuffer bb1 = ByteBuffer.allocate(135); + ByteBuffer bb2 = ByteBuffer.allocate(135); + fillBB(bb1, (byte) 5); + ByteBufferUtils.copyFromBufferToBuffer(bb1, bb2); + assertTrue(bb1.position() == bb2.position()); + assertTrue(bb1.limit() == bb2.limit()); + bb1 = ByteBuffer.allocateDirect(135); + bb2 = ByteBuffer.allocateDirect(135); + fillBB(bb1, (byte) 5); + ByteBufferUtils.copyFromBufferToBuffer(bb1, bb2); + assertTrue(bb1.position() == bb2.position()); + assertTrue(bb1.limit() == bb2.limit()); + } + @Test public void testCompareTo() { ByteBuffer bb1 = ByteBuffer.allocate(135); ByteBuffer bb2 = ByteBuffer.allocate(135);