Skip to content

Commit 81aeb06

Browse files
authored
HBASE-22504 Optimize the MultiByteBuff#get(ByteBuffer, offset, len) (#273)
1 parent 68c5129 commit 81aeb06

File tree

3 files changed

+45
-36
lines changed

3 files changed

+45
-36
lines changed

hbase-common/src/main/java/org/apache/hadoop/hbase/nio/MultiByteBuff.java

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ public void get(byte[] dst, int offset, int length) {
580580
while (length > 0) {
581581
int toRead = Math.min(length, this.curItem.remaining());
582582
ByteBufferUtils.copyFromBufferToArray(dst, this.curItem, this.curItem.position(), offset,
583-
toRead);
583+
toRead);
584584
this.curItem.position(this.curItem.position() + toRead);
585585
length -= toRead;
586586
if (length == 0) break;
@@ -598,8 +598,7 @@ public void get(int sourceOffset, byte[] dst, int offset, int length) {
598598
sourceOffset = sourceOffset - this.itemBeginPos[itemIndex];
599599
while (length > 0) {
600600
int toRead = Math.min((item.limit() - sourceOffset), length);
601-
ByteBufferUtils.copyFromBufferToArray(dst, item, sourceOffset, offset,
602-
toRead);
601+
ByteBufferUtils.copyFromBufferToArray(dst, item, sourceOffset, offset, toRead);
603602
length -= toRead;
604603
if (length == 0) break;
605604
itemIndex++;
@@ -1020,24 +1019,30 @@ public void asSubByteBuffer(int offset, int length, ObjectIntPair<ByteBuffer> pa
10201019
}
10211020
pair.setFirst(ByteBuffer.wrap(dst));
10221021
pair.setSecond(0);
1023-
return;
10241022
}
10251023

10261024
/**
10271025
* Copies the content from an this MBB to a ByteBuffer
1028-
* @param out the ByteBuffer to which the copy has to happen
1029-
* @param sourceOffset the offset in the MBB from which the elements has
1030-
* to be copied
1026+
* @param out the ByteBuffer to which the copy has to happen, its position will be advanced.
1027+
* @param sourceOffset the offset in the MBB from which the elements has to be copied
10311028
* @param length the length in the MBB upto which the elements has to be copied
10321029
*/
10331030
@Override
1034-
public void get(ByteBuffer out, int sourceOffset,
1035-
int length) {
1031+
public void get(ByteBuffer out, int sourceOffset, int length) {
10361032
checkRefCount();
1037-
// Not used from real read path actually. So not going with
1038-
// optimization
1039-
for (int i = 0; i < length; ++i) {
1040-
out.put(this.get(sourceOffset + i));
1033+
int itemIndex = getItemIndex(sourceOffset);
1034+
ByteBuffer in = this.items[itemIndex];
1035+
sourceOffset = sourceOffset - this.itemBeginPos[itemIndex];
1036+
while (length > 0) {
1037+
int toRead = Math.min(in.limit() - sourceOffset, length);
1038+
ByteBufferUtils.copyFromBufferToBuffer(in, out, sourceOffset, toRead);
1039+
length -= toRead;
1040+
if (length == 0) {
1041+
break;
1042+
}
1043+
itemIndex++;
1044+
in = this.items[itemIndex];
1045+
sourceOffset = 0;
10411046
}
10421047
}
10431048

hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -719,8 +719,8 @@ public static void copyFromBufferToBuffer(ByteBuffer in, ByteBuffer out, int sou
719719
* @param sourceOffset offset in the source buffer
720720
* @param length how many bytes to copy
721721
*/
722-
public static void copyFromBufferToBuffer(ByteBuffer in,
723-
ByteBuffer out, int sourceOffset, int length) {
722+
public static void copyFromBufferToBuffer(ByteBuffer in, ByteBuffer out, int sourceOffset,
723+
int length) {
724724
if (in.hasArray() && out.hasArray()) {
725725
System.arraycopy(in.array(), sourceOffset + in.arrayOffset(), out.array(), out.position()
726726
+ out.arrayOffset(), length);
@@ -735,27 +735,6 @@ public static void copyFromBufferToBuffer(ByteBuffer in,
735735
}
736736
}
737737

738-
/**
739-
* Find length of common prefix of two parts in the buffer
740-
* @param buffer Where parts are located.
741-
* @param offsetLeft Offset of the first part.
742-
* @param offsetRight Offset of the second part.
743-
* @param limit Maximal length of common prefix.
744-
* @return Length of prefix.
745-
*/
746-
public static int findCommonPrefix(ByteBuffer buffer, int offsetLeft,
747-
int offsetRight, int limit) {
748-
int prefix = 0;
749-
750-
for (; prefix < limit; ++prefix) {
751-
if (buffer.get(offsetLeft + prefix) != buffer.get(offsetRight + prefix)) {
752-
break;
753-
}
754-
}
755-
756-
return prefix;
757-
}
758-
759738
/**
760739
* Find length of common prefix in two arrays.
761740
* @param left Array to be compared.

hbase-common/src/test/java/org/apache/hadoop/hbase/nio/TestMultiByteBuff.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,4 +457,29 @@ public void testGetPrimitivesWithSmallIndividualBBs() {
457457
assertEquals(i, mbb.getInt());
458458
assertEquals(l, mbb.getLong());
459459
}
460+
461+
@Test
462+
public void testGetByteBufferWithOffsetAndPos() {
463+
byte[] a = Bytes.toBytes("abcd");
464+
byte[] b = Bytes.toBytes("efghijkl");
465+
ByteBuffer aa = ByteBuffer.wrap(a);
466+
ByteBuffer bb = ByteBuffer.wrap(b);
467+
MultiByteBuff mbb = new MultiByteBuff(aa, bb);
468+
ByteBuffer out = ByteBuffer.allocate(12);
469+
mbb.get(out, 0, 1);
470+
assertEquals(out.position(), 1);
471+
assertTrue(Bytes.equals(Bytes.toBytes("a"), 0, 1, out.array(), 0, 1));
472+
473+
mbb.get(out, 1, 4);
474+
assertEquals(out.position(), 5);
475+
assertTrue(Bytes.equals(Bytes.toBytes("abcde"), 0, 5, out.array(), 0, 5));
476+
477+
mbb.get(out, 10, 1);
478+
assertEquals(out.position(), 6);
479+
assertTrue(Bytes.equals(Bytes.toBytes("abcdek"), 0, 6, out.array(), 0, 6));
480+
481+
mbb.get(out, 0, 6);
482+
assertEquals(out.position(), 12);
483+
assertTrue(Bytes.equals(Bytes.toBytes("abcdekabcdef"), 0, 12, out.array(), 0, 12));
484+
}
460485
}

0 commit comments

Comments
 (0)