HBASE-20078 MultiByteBuff : bug in reading primitives when individual buffers are too small.
This commit is contained in:
parent
5bfc5745ab
commit
e83ac38d68
|
@ -260,16 +260,10 @@ public class MultiByteBuff extends ByteBuff {
|
|||
// means cur item is the last one and we wont be able to read a int. Throw exception
|
||||
throw new BufferUnderflowException();
|
||||
}
|
||||
ByteBuffer nextItem = items[itemIndex + 1];
|
||||
// Get available bytes from this item and remaining from next
|
||||
int l = 0;
|
||||
for (int i = offsetInItem; i < item.capacity(); i++) {
|
||||
for (int i = 0; i < Bytes.SIZEOF_INT; i++) {
|
||||
l <<= 8;
|
||||
l ^= ByteBufferUtils.toByte(item, i) & 0xFF;
|
||||
}
|
||||
for (int i = 0; i < Bytes.SIZEOF_INT - remainingLen; i++) {
|
||||
l <<= 8;
|
||||
l ^= ByteBufferUtils.toByte(nextItem, i) & 0xFF;
|
||||
l ^= get(index + i) & 0xFF;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
@ -310,16 +304,10 @@ public class MultiByteBuff extends ByteBuff {
|
|||
// means cur item is the last one and we wont be able to read a long. Throw exception
|
||||
throw new BufferUnderflowException();
|
||||
}
|
||||
ByteBuffer nextItem = items[itemIndex + 1];
|
||||
// Get available bytes from this item and remaining from next
|
||||
long l = 0;
|
||||
for (int i = offsetInItem; i < item.capacity(); i++) {
|
||||
for (int i = 0; i < Bytes.SIZEOF_LONG; i++) {
|
||||
l <<= 8;
|
||||
l ^= ByteBufferUtils.toByte(item, i) & 0xFF;
|
||||
}
|
||||
for (int i = 0; i < Bytes.SIZEOF_LONG - remainingLen; i++) {
|
||||
l <<= 8;
|
||||
l ^= ByteBufferUtils.toByte(nextItem, i) & 0xFF;
|
||||
l ^= get(index + i) & 0xFF;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
@ -339,28 +327,7 @@ public class MultiByteBuff extends ByteBuff {
|
|||
} else {
|
||||
itemIndex = getItemIndex(index);
|
||||
}
|
||||
ByteBuffer item = items[itemIndex];
|
||||
int offsetInItem = index - this.itemBeginPos[itemIndex];
|
||||
int remainingLen = item.limit() - offsetInItem;
|
||||
if (remainingLen >= Bytes.SIZEOF_LONG) {
|
||||
return ByteBufferUtils.toLong(item, offsetInItem);
|
||||
}
|
||||
if (items.length - 1 == itemIndex) {
|
||||
// means cur item is the last one and we wont be able to read a long. Throw exception
|
||||
throw new BufferUnderflowException();
|
||||
}
|
||||
ByteBuffer nextItem = items[itemIndex + 1];
|
||||
// Get available bytes from this item and remaining from next
|
||||
long l = 0;
|
||||
for (int i = offsetInItem; i < item.capacity(); i++) {
|
||||
l <<= 8;
|
||||
l ^= ByteBufferUtils.toByte(item, i) & 0xFF;
|
||||
}
|
||||
for (int i = 0; i < Bytes.SIZEOF_LONG - remainingLen; i++) {
|
||||
l <<= 8;
|
||||
l ^= ByteBufferUtils.toByte(nextItem, i) & 0xFF;
|
||||
}
|
||||
return l;
|
||||
return getLong(index, itemIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -513,15 +480,6 @@ public class MultiByteBuff extends ByteBuff {
|
|||
if (remaining >= Bytes.SIZEOF_SHORT) {
|
||||
return this.curItem.getShort();
|
||||
}
|
||||
if (remaining == 0) {
|
||||
if (items.length - 1 == this.curItemIndex) {
|
||||
// means cur item is the last one and we wont be able to read a long. Throw exception
|
||||
throw new BufferUnderflowException();
|
||||
}
|
||||
this.curItemIndex++;
|
||||
this.curItem = this.items[this.curItemIndex];
|
||||
return this.curItem.getShort();
|
||||
}
|
||||
short n = 0;
|
||||
n = (short) (n ^ (get() & 0xFF));
|
||||
n = (short) (n << 8);
|
||||
|
@ -540,16 +498,6 @@ public class MultiByteBuff extends ByteBuff {
|
|||
if (remaining >= Bytes.SIZEOF_INT) {
|
||||
return this.curItem.getInt();
|
||||
}
|
||||
if (remaining == 0) {
|
||||
if (items.length - 1 == this.curItemIndex) {
|
||||
// means cur item is the last one and we wont be able to read a long. Throw exception
|
||||
throw new BufferUnderflowException();
|
||||
}
|
||||
this.curItemIndex++;
|
||||
this.curItem = this.items[this.curItemIndex];
|
||||
return this.curItem.getInt();
|
||||
}
|
||||
// Get available bytes from this item and remaining from next
|
||||
int n = 0;
|
||||
for (int i = 0; i < Bytes.SIZEOF_INT; i++) {
|
||||
n <<= 8;
|
||||
|
@ -570,16 +518,6 @@ public class MultiByteBuff extends ByteBuff {
|
|||
if (remaining >= Bytes.SIZEOF_LONG) {
|
||||
return this.curItem.getLong();
|
||||
}
|
||||
if (remaining == 0) {
|
||||
if (items.length - 1 == this.curItemIndex) {
|
||||
// means cur item is the last one and we wont be able to read a long. Throw exception
|
||||
throw new BufferUnderflowException();
|
||||
}
|
||||
this.curItemIndex++;
|
||||
this.curItem = this.items[this.curItemIndex];
|
||||
return this.curItem.getLong();
|
||||
}
|
||||
// Get available bytes from this item and remaining from next
|
||||
long l = 0;
|
||||
for (int i = 0; i < Bytes.SIZEOF_LONG; i++) {
|
||||
l <<= 8;
|
||||
|
@ -613,8 +551,7 @@ public class MultiByteBuff extends ByteBuff {
|
|||
toRead);
|
||||
this.curItem.position(this.curItem.position() + toRead);
|
||||
length -= toRead;
|
||||
if (length == 0)
|
||||
break;
|
||||
if (length == 0) break;
|
||||
this.curItemIndex++;
|
||||
this.curItem = this.items[this.curItemIndex];
|
||||
offset += toRead;
|
||||
|
@ -631,8 +568,7 @@ public class MultiByteBuff extends ByteBuff {
|
|||
ByteBufferUtils.copyFromBufferToArray(dst, item, sourceOffset, offset,
|
||||
toRead);
|
||||
length -= toRead;
|
||||
if (length == 0)
|
||||
break;
|
||||
if (length == 0) break;
|
||||
itemIndex++;
|
||||
item = this.items[itemIndex];
|
||||
offset += toRead;
|
||||
|
@ -985,8 +921,7 @@ public class MultiByteBuff extends ByteBuff {
|
|||
ByteBufferUtils
|
||||
.copyFromBufferToArray(dupB, locCurItem, locCurItem.position(), offset, toRead);
|
||||
length -= toRead;
|
||||
if (length == 0)
|
||||
break;
|
||||
if (length == 0) break;
|
||||
locCurItemIndex++;
|
||||
locCurItem = this.items[locCurItemIndex];
|
||||
offset += toRead;
|
||||
|
@ -1090,8 +1025,7 @@ public class MultiByteBuff extends ByteBuff {
|
|||
// doing more reads from Channel. Only this much there for now.
|
||||
break;
|
||||
} else {
|
||||
if (this.curItemIndex >= this.limitedItemIndex)
|
||||
break;
|
||||
if (this.curItemIndex >= this.limitedItemIndex) break;
|
||||
this.curItemIndex++;
|
||||
this.curItem = this.items[this.curItemIndex];
|
||||
}
|
||||
|
|
|
@ -426,4 +426,35 @@ public class TestMultiByteBuff {
|
|||
mbb1.get(); // Now we have reached the limit
|
||||
assertFalse(mbb1.hasRemaining());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPrimitivesWithSmallIndividualBBs() {
|
||||
short s = 45;
|
||||
int i = 2345;
|
||||
long l = 75681526L;
|
||||
ByteBuffer bb = ByteBuffer.allocate(14);
|
||||
bb.putShort(s);
|
||||
bb.putInt(i);
|
||||
bb.putLong(l);
|
||||
|
||||
ByteBuffer bb1 = ((ByteBuffer) bb.duplicate().position(0).limit(1)).slice();
|
||||
ByteBuffer bb2 = ((ByteBuffer) bb.duplicate().position(1).limit(3)).slice();
|
||||
ByteBuffer bb3 = ((ByteBuffer) bb.duplicate().position(3).limit(5)).slice();
|
||||
ByteBuffer bb4 = ((ByteBuffer) bb.duplicate().position(5).limit(11)).slice();
|
||||
ByteBuffer bb5 = ((ByteBuffer) bb.duplicate().position(11).limit(12)).slice();
|
||||
ByteBuffer bb6 = ((ByteBuffer) bb.duplicate().position(12).limit(14)).slice();
|
||||
MultiByteBuff mbb = new MultiByteBuff(bb1, bb2, bb3, bb4, bb5, bb6);
|
||||
assertEquals(s, mbb.getShortAfterPosition(0));
|
||||
assertEquals(i, mbb.getIntAfterPosition(2));
|
||||
assertEquals(l, mbb.getLongAfterPosition(6));
|
||||
|
||||
assertEquals(s, mbb.getShort(0));
|
||||
assertEquals(i, mbb.getInt(2));
|
||||
assertEquals(l, mbb.getLong(6));
|
||||
|
||||
mbb.position(0);
|
||||
assertEquals(s, mbb.getShort());
|
||||
assertEquals(i, mbb.getInt());
|
||||
assertEquals(l, mbb.getLong());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue