* More tests

* Fixed bugs related with bulk byte transfer
This commit is contained in:
Trustin Lee 2008-08-26 07:12:04 +00:00
parent 6801298956
commit 8f3799c02e
4 changed files with 331 additions and 28 deletions

View File

@ -202,9 +202,6 @@ public class ByteBufferBackedChannelBuffer extends AbstractChannelBuffer {
public int setBytes(int index, InputStream in, int length) public int setBytes(int index, InputStream in, int length)
throws IOException { throws IOException {
if (length == 0) {
return 0;
}
int readBytes = 0; int readBytes = 0;
@ -225,7 +222,8 @@ public class ByteBufferBackedChannelBuffer extends AbstractChannelBuffer {
} while (length > 0); } while (length > 0);
} else { } else {
byte[] tmp = new byte[length]; byte[] tmp = new byte[length];
for (int i = 0; i < tmp.length;) { int i = 0;
do {
int localReadBytes = in.read(tmp, i, tmp.length - i); int localReadBytes = in.read(tmp, i, tmp.length - i);
if (localReadBytes < 0) { if (localReadBytes < 0) {
if (readBytes == 0) { if (readBytes == 0) {
@ -234,9 +232,10 @@ public class ByteBufferBackedChannelBuffer extends AbstractChannelBuffer {
break; break;
} }
} }
readBytes += localReadBytes;
i += readBytes; i += readBytes;
} } while (i < tmp.length);
((ByteBuffer) buffer.duplicate().position(index)).get(tmp); ((ByteBuffer) buffer.duplicate().position(index)).put(tmp);
} }
return readBytes; return readBytes;

View File

@ -353,7 +353,7 @@ public class CompositeChannelBuffer extends AbstractChannelBuffer {
int i = sliceId; int i = sliceId;
int readBytes = 0; int readBytes = 0;
while (length > 0) { do {
ChannelBuffer s = slices[i]; ChannelBuffer s = slices[i];
int adjustment = indices[i]; int adjustment = indices[i];
int localLength = Math.min(length, s.capacity() - (index - adjustment)); int localLength = Math.min(length, s.capacity() - (index - adjustment));
@ -365,10 +365,18 @@ public class CompositeChannelBuffer extends AbstractChannelBuffer {
break; break;
} }
} }
if (localReadBytes == localLength) {
index += localLength; index += localLength;
length -= localLength; length -= localLength;
readBytes += localLength;
i ++; i ++;
} else {
index += localReadBytes;
length -= localReadBytes;
readBytes += localReadBytes;
} }
} while (length > 0);
return readBytes; return readBytes;
} }
@ -381,22 +389,26 @@ public class CompositeChannelBuffer extends AbstractChannelBuffer {
} }
int i = sliceId; int i = sliceId;
int writtenBytes = 0; int readBytes = 0;
while (length > 0) { do {
ChannelBuffer s = slices[i]; ChannelBuffer s = slices[i];
int adjustment = indices[i]; int adjustment = indices[i];
int localLength = Math.min(length, s.capacity() - (index - adjustment)); int localLength = Math.min(length, s.capacity() - (index - adjustment));
int localWrittenBytes = s.setBytes(index - adjustment, in, localLength); int localReadBytes = s.setBytes(index - adjustment, in, localLength);
writtenBytes += localWrittenBytes;
if (localLength != localWrittenBytes) { if (localReadBytes == localLength) {
break;
}
index += localLength; index += localLength;
length -= localLength; length -= localLength;
readBytes += localLength;
i ++; i ++;
} else {
index += localReadBytes;
length -= localReadBytes;
readBytes += localReadBytes;
} }
} while (length > 0);
return writtenBytes; return readBytes;
} }
public ChannelBuffer duplicate() { public ChannelBuffer duplicate() {

View File

@ -115,7 +115,7 @@ public abstract class HeapChannelBuffer extends AbstractChannelBuffer {
public int setBytes(int index, InputStream in, int length) throws IOException { public int setBytes(int index, InputStream in, int length) throws IOException {
int readBytes = 0; int readBytes = 0;
while (length > 0) { do {
int localReadBytes = in.read(array, index, length); int localReadBytes = in.read(array, index, length);
if (localReadBytes < 0) { if (localReadBytes < 0) {
if (readBytes == 0) { if (readBytes == 0) {
@ -127,7 +127,7 @@ public abstract class HeapChannelBuffer extends AbstractChannelBuffer {
readBytes += localReadBytes; readBytes += localReadBytes;
index += localReadBytes; index += localReadBytes;
length -= localReadBytes; length -= localReadBytes;
} } while (length > 0);
return readBytes; return readBytes;
} }
@ -136,7 +136,7 @@ public abstract class HeapChannelBuffer extends AbstractChannelBuffer {
ByteBuffer buf = ByteBuffer.wrap(array, index, length); ByteBuffer buf = ByteBuffer.wrap(array, index, length);
int readBytes = 0; int readBytes = 0;
while (readBytes < length) { do {
int localReadBytes = in.read(buf); int localReadBytes = in.read(buf);
if (localReadBytes < 0) { if (localReadBytes < 0) {
if (readBytes == 0) { if (readBytes == 0) {
@ -148,7 +148,7 @@ public abstract class HeapChannelBuffer extends AbstractChannelBuffer {
break; break;
} }
readBytes += localReadBytes; readBytes += localReadBytes;
} } while (readBytes < length);
return readBytes; return readBytes;
} }

View File

@ -25,7 +25,10 @@ package org.jboss.netty.buffer;
import static org.jboss.netty.buffer.ChannelBuffers.*; import static org.jboss.netty.buffer.ChannelBuffers.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Random; import java.util.Random;
import org.junit.After; import org.junit.After;
@ -427,6 +430,24 @@ public abstract class AbstractChannelBufferTest {
} }
} }
@Test
public void testSetZero() {
buffer.clear();
while (buffer.writable()) {
buffer.writeByte((byte) 0xFF);
}
for (int i = 0; i < buffer.capacity();) {
int length = Math.min(buffer.capacity() - i, random.nextInt(32));
buffer.setZero(i, length);
i += length;
}
for (int i = 0; i < buffer.capacity(); i ++) {
assertEquals(0, buffer.getByte(i));
}
}
@Test @Test
public void testSequentialByteAccess() { public void testSequentialByteAccess() {
buffer.writerIndex(0); buffer.writerIndex(0);
@ -455,6 +476,34 @@ public abstract class AbstractChannelBufferTest {
assertFalse(buffer.writable()); assertFalse(buffer.writable());
} }
@Test
public void testSequentialUnsignedByteAccess() {
buffer.writerIndex(0);
for (int i = 0; i < buffer.capacity(); i ++) {
byte value = (byte) random.nextInt();
assertEquals(i, buffer.writerIndex());
assertTrue(buffer.writable());
buffer.writeByte(value);
}
assertEquals(0, buffer.readerIndex());
assertEquals(buffer.capacity(), buffer.writerIndex());
assertFalse(buffer.writable());
random.setSeed(seed);
for (int i = 0; i < buffer.capacity(); i ++) {
int value = random.nextInt() & 0xFF;
assertEquals(i, buffer.readerIndex());
assertTrue(buffer.readable());
assertEquals(value, buffer.readUnsignedByte());
}
assertEquals(buffer.capacity(), buffer.readerIndex());
assertEquals(buffer.capacity(), buffer.writerIndex());
assertFalse(buffer.readable());
assertFalse(buffer.writable());
}
@Test @Test
public void testSequentialShortAccess() { public void testSequentialShortAccess() {
buffer.writerIndex(0); buffer.writerIndex(0);
@ -483,8 +532,64 @@ public abstract class AbstractChannelBufferTest {
assertFalse(buffer.writable()); assertFalse(buffer.writable());
} }
@Test
public void testSequentialUnsignedShortAccess() {
buffer.writerIndex(0);
for (int i = 0; i < buffer.capacity(); i += 2) {
short value = (short) random.nextInt();
assertEquals(i, buffer.writerIndex());
assertTrue(buffer.writable());
buffer.writeShort(value);
}
assertEquals(0, buffer.readerIndex());
assertEquals(buffer.capacity(), buffer.writerIndex());
assertFalse(buffer.writable());
random.setSeed(seed);
for (int i = 0; i < buffer.capacity(); i += 2) {
int value = random.nextInt() & 0xFFFF;
assertEquals(i, buffer.readerIndex());
assertTrue(buffer.readable());
assertEquals(value, buffer.readUnsignedShort());
}
assertEquals(buffer.capacity(), buffer.readerIndex());
assertEquals(buffer.capacity(), buffer.writerIndex());
assertFalse(buffer.readable());
assertFalse(buffer.writable());
}
@Test @Test
public void testSequentialMediumAccess() { public void testSequentialMediumAccess() {
buffer.writerIndex(0);
for (int i = 0; i < buffer.capacity() / 3 * 3; i += 3) {
int value = random.nextInt();
assertEquals(i, buffer.writerIndex());
assertTrue(buffer.writable());
buffer.writeMedium(value);
}
assertEquals(0, buffer.readerIndex());
assertEquals(buffer.capacity() / 3 * 3, buffer.writerIndex());
assertEquals(buffer.capacity() % 3, buffer.writableBytes());
random.setSeed(seed);
for (int i = 0; i < buffer.capacity() / 3 * 3; i += 3) {
int value = random.nextInt() << 8 >> 8;
assertEquals(i, buffer.readerIndex());
assertTrue(buffer.readable());
assertEquals(value, buffer.readMedium());
}
assertEquals(buffer.capacity() / 3 * 3, buffer.readerIndex());
assertEquals(buffer.capacity() / 3 * 3, buffer.writerIndex());
assertEquals(0, buffer.readableBytes());
assertEquals(buffer.capacity() % 3, buffer.writableBytes());
}
@Test
public void testSequentialUnsignedMediumAccess() {
buffer.writerIndex(0); buffer.writerIndex(0);
for (int i = 0; i < buffer.capacity() / 3 * 3; i += 3) { for (int i = 0; i < buffer.capacity() / 3 * 3; i += 3) {
int value = random.nextInt() & 0x00FFFFFF; int value = random.nextInt() & 0x00FFFFFF;
@ -539,6 +644,34 @@ public abstract class AbstractChannelBufferTest {
assertFalse(buffer.writable()); assertFalse(buffer.writable());
} }
@Test
public void testSequentialUnsignedIntAccess() {
buffer.writerIndex(0);
for (int i = 0; i < buffer.capacity(); i += 4) {
int value = random.nextInt();
assertEquals(i, buffer.writerIndex());
assertTrue(buffer.writable());
buffer.writeInt(value);
}
assertEquals(0, buffer.readerIndex());
assertEquals(buffer.capacity(), buffer.writerIndex());
assertFalse(buffer.writable());
random.setSeed(seed);
for (int i = 0; i < buffer.capacity(); i += 4) {
long value = random.nextInt() & 0xFFFFFFFFL;
assertEquals(i, buffer.readerIndex());
assertTrue(buffer.readable());
assertEquals(value, buffer.readUnsignedInt());
}
assertEquals(buffer.capacity(), buffer.readerIndex());
assertEquals(buffer.capacity(), buffer.writerIndex());
assertFalse(buffer.readable());
assertFalse(buffer.writable());
}
@Test @Test
public void testSequentialLongAccess() { public void testSequentialLongAccess() {
buffer.writerIndex(0); buffer.writerIndex(0);
@ -588,7 +721,75 @@ public abstract class AbstractChannelBufferTest {
} }
@Test @Test
public void testRandomHeapBufferTransfer() { public void testRandomByteArrayTransfer1() {
byte[] value= new byte[BLOCK_SIZE];
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
random.nextBytes(value);
buffer.setBytes(i, value);
}
random.setSeed(seed);
byte[] expectedValueContent = new byte[BLOCK_SIZE];
ChannelBuffer expectedValue = wrappedBuffer(expectedValueContent);
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
random.nextBytes(expectedValueContent);
buffer.getBytes(i, value);
for (int j = 0; j < BLOCK_SIZE; j ++) {
assertEquals(expectedValue.getByte(j), value[j]);
}
}
}
@Test
public void testRandomByteArrayTransfer2() {
byte[] value= new byte[BLOCK_SIZE * 2];
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
random.nextBytes(value);
buffer.setBytes(i, value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE);
}
random.setSeed(seed);
byte[] expectedValueContent = new byte[BLOCK_SIZE * 2];
ChannelBuffer expectedValue = wrappedBuffer(expectedValueContent);
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
random.nextBytes(expectedValueContent);
int valueOffset = random.nextInt(BLOCK_SIZE);
buffer.getBytes(i, value, valueOffset, BLOCK_SIZE);
for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
assertEquals(expectedValue.getByte(j), value[j]);
}
}
}
@Test
public void testRandomHeapBufferTransfer1() {
byte[] valueContent = new byte[BLOCK_SIZE];
ChannelBuffer value = wrappedBuffer(valueContent);
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
random.nextBytes(valueContent);
value.setIndex(0, BLOCK_SIZE);
buffer.setBytes(i, value);
assertEquals(BLOCK_SIZE, value.readerIndex());
assertEquals(BLOCK_SIZE, value.writerIndex());
}
random.setSeed(seed);
byte[] expectedValueContent = new byte[BLOCK_SIZE];
ChannelBuffer expectedValue = wrappedBuffer(expectedValueContent);
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
random.nextBytes(expectedValueContent);
value.clear();
buffer.getBytes(i, value);
assertEquals(0, value.readerIndex());
assertEquals(BLOCK_SIZE, value.writerIndex());
for (int j = 0; j < BLOCK_SIZE; j ++) {
assertEquals(expectedValue.getByte(j), value.getByte(j));
}
}
}
@Test
public void testRandomHeapBufferTransfer2() {
byte[] valueContent = new byte[BLOCK_SIZE * 2]; byte[] valueContent = new byte[BLOCK_SIZE * 2];
ChannelBuffer value = wrappedBuffer(valueContent); ChannelBuffer value = wrappedBuffer(valueContent);
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
@ -656,6 +857,56 @@ public abstract class AbstractChannelBufferTest {
} }
} }
@Test
public void testSequentialByteArrayTransfer1() {
byte[] value= new byte[BLOCK_SIZE];
buffer.writerIndex(0);
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
random.nextBytes(value);
assertEquals(0, buffer.readerIndex());
assertEquals(i, buffer.writerIndex());
buffer.writeBytes(value);
}
random.setSeed(seed);
byte[] expectedValue = new byte[BLOCK_SIZE];
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
random.nextBytes(expectedValue);
assertEquals(i, buffer.readerIndex());
assertEquals(CAPACITY, buffer.writerIndex());
buffer.readBytes(value);
for (int j = 0; j < BLOCK_SIZE; j ++) {
assertEquals(expectedValue[j], value[j]);
}
}
}
@Test
public void testSequentialByteArrayTransfer2() {
byte[] value = new byte[BLOCK_SIZE * 2];
buffer.writerIndex(0);
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
random.nextBytes(value);
assertEquals(0, buffer.readerIndex());
assertEquals(i, buffer.writerIndex());
int readerIndex = random.nextInt(BLOCK_SIZE);
buffer.writeBytes(value, readerIndex, BLOCK_SIZE);
}
random.setSeed(seed);
byte[] expectedValue= new byte[BLOCK_SIZE * 2];
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
random.nextBytes(expectedValue);
int valueOffset = random.nextInt(BLOCK_SIZE);
assertEquals(i, buffer.readerIndex());
assertEquals(CAPACITY, buffer.writerIndex());
buffer.readBytes(value, valueOffset, BLOCK_SIZE);
for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
assertEquals(expectedValue[j], value[j]);
}
}
}
@Test @Test
public void testSequentialHeapBufferTransfer1() { public void testSequentialHeapBufferTransfer1() {
byte[] valueContent = new byte[BLOCK_SIZE * 2]; byte[] valueContent = new byte[BLOCK_SIZE * 2];
@ -820,6 +1071,28 @@ public abstract class AbstractChannelBufferTest {
} }
} }
@Test
public void testWriteZero() {
buffer.clear();
while (buffer.writable()) {
buffer.writeByte((byte) 0xFF);
}
buffer.clear();
for (int i = 0; i < buffer.capacity();) {
int length = Math.min(buffer.capacity() - i, random.nextInt(32));
buffer.writeZero(length);
i += length;
}
assertEquals(0, buffer.readerIndex());
assertEquals(buffer.capacity(), buffer.writerIndex());
for (int i = 0; i < buffer.capacity(); i ++) {
assertEquals(0, buffer.getByte(i));
}
}
@Test @Test
public void testDiscardReadBytes() { public void testDiscardReadBytes() {
buffer.writerIndex(0); buffer.writerIndex(0);
@ -862,6 +1135,25 @@ public abstract class AbstractChannelBufferTest {
assertEquals(CAPACITY / 3 - 1, buffer.writerIndex()); assertEquals(CAPACITY / 3 - 1, buffer.writerIndex());
} }
@Test
public void testStreamTransfer() throws Exception {
byte[] expected = new byte[buffer.capacity()];
random.nextBytes(expected);
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
ByteArrayInputStream in = new ByteArrayInputStream(expected, i, BLOCK_SIZE);
assertEquals(BLOCK_SIZE, buffer.setBytes(i, in, BLOCK_SIZE));
assertEquals(-1, buffer.setBytes(i, in, 0));
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
buffer.getBytes(i, out, BLOCK_SIZE);
}
assertTrue(Arrays.equals(expected, out.toByteArray()));
}
@Test @Test
public void testCopy() { public void testCopy() {
for (int i = 0; i < buffer.capacity(); i ++) { for (int i = 0; i < buffer.capacity(); i ++) {