Add ReferenceCountUtil.releaseLater() to make writing tests easy with ReferenceCounteds
This commit is contained in:
parent
ea3143a1ee
commit
0f3451c227
@ -30,10 +30,8 @@ import java.nio.ByteBuffer;
|
|||||||
import java.nio.channels.Channels;
|
import java.nio.channels.Channels;
|
||||||
import java.nio.channels.GatheringByteChannel;
|
import java.nio.channels.GatheringByteChannel;
|
||||||
import java.nio.channels.WritableByteChannel;
|
import java.nio.channels.WritableByteChannel;
|
||||||
import java.util.ArrayDeque;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
@ -43,6 +41,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import static io.netty.buffer.Unpooled.*;
|
import static io.netty.buffer.Unpooled.*;
|
||||||
|
import static io.netty.util.ReferenceCountUtil.*;
|
||||||
import static io.netty.util.internal.EmptyArrays.*;
|
import static io.netty.util.internal.EmptyArrays.*;
|
||||||
import static org.hamcrest.CoreMatchers.*;
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
@ -55,13 +54,6 @@ public abstract class AbstractByteBufTest {
|
|||||||
private static final int CAPACITY = 4096; // Must be even
|
private static final int CAPACITY = 4096; // Must be even
|
||||||
private static final int BLOCK_SIZE = 128;
|
private static final int BLOCK_SIZE = 128;
|
||||||
|
|
||||||
private static final Queue<ByteBuf> freeLaterQueue = new ArrayDeque<ByteBuf>();
|
|
||||||
|
|
||||||
protected static <T extends ByteBuf> T freeLater(T buf) {
|
|
||||||
freeLaterQueue.add(buf);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
private long seed;
|
private long seed;
|
||||||
private Random random;
|
private Random random;
|
||||||
private ByteBuf buffer;
|
private ByteBuf buffer;
|
||||||
@ -93,17 +85,6 @@ public abstract class AbstractByteBufTest {
|
|||||||
}
|
}
|
||||||
buffer = null;
|
buffer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
ByteBuf buf = freeLaterQueue.poll();
|
|
||||||
if (buf == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf.refCnt() > 0) {
|
|
||||||
buf.release(buf.refCnt());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -888,7 +869,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testRandomDirectBufferTransfer() {
|
public void testRandomDirectBufferTransfer() {
|
||||||
byte[] tmp = new byte[BLOCK_SIZE * 2];
|
byte[] tmp = new byte[BLOCK_SIZE * 2];
|
||||||
ByteBuf value = freeLater(directBuffer(BLOCK_SIZE * 2));
|
ByteBuf value = releaseLater(directBuffer(BLOCK_SIZE * 2));
|
||||||
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) {
|
||||||
random.nextBytes(tmp);
|
random.nextBytes(tmp);
|
||||||
value.setBytes(0, tmp, 0, value.capacity());
|
value.setBytes(0, tmp, 0, value.capacity());
|
||||||
@ -896,7 +877,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
random.setSeed(seed);
|
random.setSeed(seed);
|
||||||
ByteBuf expectedValue = freeLater(directBuffer(BLOCK_SIZE * 2));
|
ByteBuf expectedValue = releaseLater(directBuffer(BLOCK_SIZE * 2));
|
||||||
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) {
|
||||||
random.nextBytes(tmp);
|
random.nextBytes(tmp);
|
||||||
expectedValue.setBytes(0, tmp, 0, expectedValue.capacity());
|
expectedValue.setBytes(0, tmp, 0, expectedValue.capacity());
|
||||||
@ -1052,7 +1033,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSequentialDirectBufferTransfer1() {
|
public void testSequentialDirectBufferTransfer1() {
|
||||||
byte[] valueContent = new byte[BLOCK_SIZE * 2];
|
byte[] valueContent = new byte[BLOCK_SIZE * 2];
|
||||||
ByteBuf value = freeLater(directBuffer(BLOCK_SIZE * 2));
|
ByteBuf value = releaseLater(directBuffer(BLOCK_SIZE * 2));
|
||||||
buffer.writerIndex(0);
|
buffer.writerIndex(0);
|
||||||
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) {
|
||||||
random.nextBytes(valueContent);
|
random.nextBytes(valueContent);
|
||||||
@ -1066,7 +1047,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
|
|
||||||
random.setSeed(seed);
|
random.setSeed(seed);
|
||||||
byte[] expectedValueContent = new byte[BLOCK_SIZE * 2];
|
byte[] expectedValueContent = new byte[BLOCK_SIZE * 2];
|
||||||
ByteBuf expectedValue = freeLater(wrappedBuffer(expectedValueContent));
|
ByteBuf expectedValue = releaseLater(wrappedBuffer(expectedValueContent));
|
||||||
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) {
|
||||||
random.nextBytes(expectedValueContent);
|
random.nextBytes(expectedValueContent);
|
||||||
int valueOffset = random.nextInt(BLOCK_SIZE);
|
int valueOffset = random.nextInt(BLOCK_SIZE);
|
||||||
@ -1085,7 +1066,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSequentialDirectBufferTransfer2() {
|
public void testSequentialDirectBufferTransfer2() {
|
||||||
byte[] valueContent = new byte[BLOCK_SIZE * 2];
|
byte[] valueContent = new byte[BLOCK_SIZE * 2];
|
||||||
ByteBuf value = freeLater(directBuffer(BLOCK_SIZE * 2));
|
ByteBuf value = releaseLater(directBuffer(BLOCK_SIZE * 2));
|
||||||
buffer.writerIndex(0);
|
buffer.writerIndex(0);
|
||||||
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) {
|
||||||
random.nextBytes(valueContent);
|
random.nextBytes(valueContent);
|
||||||
@ -1103,7 +1084,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
|
|
||||||
random.setSeed(seed);
|
random.setSeed(seed);
|
||||||
byte[] expectedValueContent = new byte[BLOCK_SIZE * 2];
|
byte[] expectedValueContent = new byte[BLOCK_SIZE * 2];
|
||||||
ByteBuf expectedValue = freeLater(wrappedBuffer(expectedValueContent));
|
ByteBuf expectedValue = releaseLater(wrappedBuffer(expectedValueContent));
|
||||||
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) {
|
||||||
random.nextBytes(expectedValueContent);
|
random.nextBytes(expectedValueContent);
|
||||||
value.setBytes(0, valueContent);
|
value.setBytes(0, valueContent);
|
||||||
@ -1308,7 +1289,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
for (int i = 0; i < buffer.capacity(); i += 4) {
|
for (int i = 0; i < buffer.capacity(); i += 4) {
|
||||||
buffer.writeInt(i);
|
buffer.writeInt(i);
|
||||||
}
|
}
|
||||||
ByteBuf copy = freeLater(copiedBuffer(buffer));
|
ByteBuf copy = releaseLater(copiedBuffer(buffer));
|
||||||
|
|
||||||
// Make sure there's no effect if called when readerIndex is 0.
|
// Make sure there's no effect if called when readerIndex is 0.
|
||||||
buffer.readerIndex(CAPACITY / 4);
|
buffer.readerIndex(CAPACITY / 4);
|
||||||
@ -1360,7 +1341,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
for (int i = 0; i < buffer.capacity(); i ++) {
|
for (int i = 0; i < buffer.capacity(); i ++) {
|
||||||
buffer.writeByte((byte) i);
|
buffer.writeByte((byte) i);
|
||||||
}
|
}
|
||||||
ByteBuf copy = freeLater(copiedBuffer(buffer));
|
ByteBuf copy = releaseLater(copiedBuffer(buffer));
|
||||||
|
|
||||||
// Discard the first (CAPACITY / 2 - 1) bytes.
|
// Discard the first (CAPACITY / 2 - 1) bytes.
|
||||||
buffer.setIndex(CAPACITY / 2 - 1, CAPACITY - 1);
|
buffer.setIndex(CAPACITY / 2 - 1, CAPACITY - 1);
|
||||||
@ -1426,7 +1407,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
buffer.setIndex(readerIndex, writerIndex);
|
buffer.setIndex(readerIndex, writerIndex);
|
||||||
|
|
||||||
// Make sure all properties are copied.
|
// Make sure all properties are copied.
|
||||||
ByteBuf copy = freeLater(buffer.copy());
|
ByteBuf copy = releaseLater(buffer.copy());
|
||||||
assertEquals(0, copy.readerIndex());
|
assertEquals(0, copy.readerIndex());
|
||||||
assertEquals(buffer.readableBytes(), copy.writerIndex());
|
assertEquals(buffer.readableBytes(), copy.writerIndex());
|
||||||
assertEquals(buffer.readableBytes(), copy.capacity());
|
assertEquals(buffer.readableBytes(), copy.capacity());
|
||||||
@ -1635,8 +1616,8 @@ public abstract class AbstractByteBufTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHashCode() {
|
public void testHashCode() {
|
||||||
ByteBuf elemA = freeLater(buffer(15));
|
ByteBuf elemA = releaseLater(buffer(15));
|
||||||
ByteBuf elemB = freeLater(directBuffer(15));
|
ByteBuf elemB = releaseLater(directBuffer(15));
|
||||||
elemA.writeBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 });
|
elemA.writeBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 });
|
||||||
elemB.writeBytes(new byte[] { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9 });
|
elemB.writeBytes(new byte[] { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9 });
|
||||||
|
|
||||||
@ -1645,9 +1626,9 @@ public abstract class AbstractByteBufTest {
|
|||||||
set.add(elemB);
|
set.add(elemB);
|
||||||
|
|
||||||
assertEquals(2, set.size());
|
assertEquals(2, set.size());
|
||||||
assertTrue(set.contains(freeLater(elemA.copy())));
|
assertTrue(set.contains(releaseLater(elemA.copy())));
|
||||||
|
|
||||||
ByteBuf elemBCopy = freeLater(elemB.copy());
|
ByteBuf elemBCopy = releaseLater(elemB.copy());
|
||||||
assertTrue(set.contains(elemBCopy));
|
assertTrue(set.contains(elemBCopy));
|
||||||
|
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
@ -1714,7 +1695,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
i ++;
|
i++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}), is(stop));
|
}), is(stop));
|
||||||
@ -1755,7 +1736,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void testInternalNioBuffer(int a) {
|
private void testInternalNioBuffer(int a) {
|
||||||
ByteBuf buffer = freeLater(newBuffer(2));
|
ByteBuf buffer = releaseLater(newBuffer(2));
|
||||||
ByteBuffer buf = buffer.internalNioBuffer(0, 1);
|
ByteBuffer buf = buffer.internalNioBuffer(0, 1);
|
||||||
assertEquals(1, buf.remaining());
|
assertEquals(1, buf.remaining());
|
||||||
|
|
||||||
@ -1786,7 +1767,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
final byte[] bytes = new byte[8];
|
final byte[] bytes = new byte[8];
|
||||||
random.nextBytes(bytes);
|
random.nextBytes(bytes);
|
||||||
|
|
||||||
final ByteBuf buffer = freeLater(newBuffer(8));
|
final ByteBuf buffer = releaseLater(newBuffer(8));
|
||||||
buffer.writeBytes(bytes);
|
buffer.writeBytes(bytes);
|
||||||
final CountDownLatch latch = new CountDownLatch(60000);
|
final CountDownLatch latch = new CountDownLatch(60000);
|
||||||
final CyclicBarrier barrier = new CyclicBarrier(11);
|
final CyclicBarrier barrier = new CyclicBarrier(11);
|
||||||
@ -1840,7 +1821,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
final byte[] bytes = new byte[8];
|
final byte[] bytes = new byte[8];
|
||||||
random.nextBytes(bytes);
|
random.nextBytes(bytes);
|
||||||
|
|
||||||
final ByteBuf buffer = freeLater(newBuffer(8));
|
final ByteBuf buffer = releaseLater(newBuffer(8));
|
||||||
buffer.writeBytes(bytes);
|
buffer.writeBytes(bytes);
|
||||||
final CountDownLatch latch = new CountDownLatch(60000);
|
final CountDownLatch latch = new CountDownLatch(60000);
|
||||||
final CyclicBarrier barrier = new CyclicBarrier(11);
|
final CyclicBarrier barrier = new CyclicBarrier(11);
|
||||||
@ -1894,7 +1875,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
final byte[] bytes = new byte[8];
|
final byte[] bytes = new byte[8];
|
||||||
random.nextBytes(bytes);
|
random.nextBytes(bytes);
|
||||||
|
|
||||||
final ByteBuf buffer = freeLater(newBuffer(8));
|
final ByteBuf buffer = releaseLater(newBuffer(8));
|
||||||
buffer.writeBytes(bytes);
|
buffer.writeBytes(bytes);
|
||||||
final AtomicReference<Throwable> cause = new AtomicReference<Throwable>();
|
final AtomicReference<Throwable> cause = new AtomicReference<Throwable>();
|
||||||
final CountDownLatch latch = new CountDownLatch(60000);
|
final CountDownLatch latch = new CountDownLatch(60000);
|
||||||
@ -1937,15 +1918,15 @@ public abstract class AbstractByteBufTest {
|
|||||||
|
|
||||||
@Test(expected = IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void readByteThrowsIndexOutOfBoundsException() {
|
public void readByteThrowsIndexOutOfBoundsException() {
|
||||||
final ByteBuf buffer = freeLater(newBuffer(8));
|
final ByteBuf buffer = releaseLater(newBuffer(8));
|
||||||
buffer.writeByte(0);
|
buffer.writeByte(0);
|
||||||
assertEquals((byte) 0 , buffer.readByte());
|
assertEquals((byte) 0, buffer.readByte());
|
||||||
buffer.readByte();
|
buffer.readByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNioBufferExposeOnlyRegion() {
|
public void testNioBufferExposeOnlyRegion() {
|
||||||
final ByteBuf buffer = freeLater(newBuffer(8));
|
final ByteBuf buffer = releaseLater(newBuffer(8));
|
||||||
byte[] data = new byte[8];
|
byte[] data = new byte[8];
|
||||||
random.nextBytes(data);
|
random.nextBytes(data);
|
||||||
buffer.writeBytes(data);
|
buffer.writeBytes(data);
|
||||||
|
@ -24,6 +24,7 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static io.netty.buffer.Unpooled.*;
|
import static io.netty.buffer.Unpooled.*;
|
||||||
|
import static io.netty.util.ReferenceCountUtil.*;
|
||||||
import static io.netty.util.internal.EmptyArrays.*;
|
import static io.netty.util.internal.EmptyArrays.*;
|
||||||
import static org.hamcrest.CoreMatchers.*;
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
@ -123,7 +124,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
public void testDiscardReadBytes3() {
|
public void testDiscardReadBytes3() {
|
||||||
ByteBuf a, b;
|
ByteBuf a, b;
|
||||||
a = wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).order(order);
|
a = wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).order(order);
|
||||||
b = freeLater(wrappedBuffer(
|
b = releaseLater(wrappedBuffer(
|
||||||
wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 0, 5).order(order),
|
wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 0, 5).order(order),
|
||||||
wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 5, 5).order(order)));
|
wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 5, 5).order(order)));
|
||||||
a.skipBytes(6);
|
a.skipBytes(6);
|
||||||
@ -199,7 +200,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFullConsolidation() {
|
public void testFullConsolidation() {
|
||||||
CompositeByteBuf buf = freeLater(compositeBuffer(Integer.MAX_VALUE));
|
CompositeByteBuf buf = releaseLater(compositeBuffer(Integer.MAX_VALUE));
|
||||||
buf.addComponent(wrappedBuffer(new byte[] { 1 }));
|
buf.addComponent(wrappedBuffer(new byte[] { 1 }));
|
||||||
buf.addComponent(wrappedBuffer(new byte[] { 2, 3 }));
|
buf.addComponent(wrappedBuffer(new byte[] { 2, 3 }));
|
||||||
buf.addComponent(wrappedBuffer(new byte[] { 4, 5, 6 }));
|
buf.addComponent(wrappedBuffer(new byte[] { 4, 5, 6 }));
|
||||||
@ -213,7 +214,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRangedConsolidation() {
|
public void testRangedConsolidation() {
|
||||||
CompositeByteBuf buf = freeLater(compositeBuffer(Integer.MAX_VALUE));
|
CompositeByteBuf buf = releaseLater(compositeBuffer(Integer.MAX_VALUE));
|
||||||
buf.addComponent(wrappedBuffer(new byte[] { 1 }));
|
buf.addComponent(wrappedBuffer(new byte[] { 1 }));
|
||||||
buf.addComponent(wrappedBuffer(new byte[] { 2, 3 }));
|
buf.addComponent(wrappedBuffer(new byte[] { 2, 3 }));
|
||||||
buf.addComponent(wrappedBuffer(new byte[] { 4, 5, 6 }));
|
buf.addComponent(wrappedBuffer(new byte[] { 4, 5, 6 }));
|
||||||
@ -248,66 +249,66 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
ByteBuf a, b;
|
ByteBuf a, b;
|
||||||
// XXX Same tests with several buffers in wrappedCheckedBuffer
|
// XXX Same tests with several buffers in wrappedCheckedBuffer
|
||||||
// Different length.
|
// Different length.
|
||||||
a = freeLater(wrappedBuffer(new byte[] { 1 }).order(order));
|
a = releaseLater(wrappedBuffer(new byte[] { 1 }).order(order));
|
||||||
b = freeLater(wrappedBuffer(
|
b = releaseLater(wrappedBuffer(
|
||||||
wrappedBuffer(new byte[] { 1 }).order(order),
|
wrappedBuffer(new byte[] { 1 }).order(order),
|
||||||
wrappedBuffer(new byte[] { 2 }).order(order)));
|
wrappedBuffer(new byte[] { 2 }).order(order)));
|
||||||
assertFalse(ByteBufUtil.equals(a, b));
|
assertFalse(ByteBufUtil.equals(a, b));
|
||||||
|
|
||||||
// Same content, same firstIndex, short length.
|
// Same content, same firstIndex, short length.
|
||||||
a = freeLater(wrappedBuffer(new byte[] { 1, 2, 3 }).order(order));
|
a = releaseLater(wrappedBuffer(new byte[] { 1, 2, 3 }).order(order));
|
||||||
b = freeLater(wrappedBuffer(
|
b = releaseLater(wrappedBuffer(
|
||||||
wrappedBuffer(new byte[]{1}).order(order),
|
wrappedBuffer(new byte[]{1}).order(order),
|
||||||
wrappedBuffer(new byte[]{2}).order(order),
|
wrappedBuffer(new byte[]{2}).order(order),
|
||||||
wrappedBuffer(new byte[]{3}).order(order)));
|
wrappedBuffer(new byte[]{3}).order(order)));
|
||||||
assertTrue(ByteBufUtil.equals(a, b));
|
assertTrue(ByteBufUtil.equals(a, b));
|
||||||
|
|
||||||
// Same content, different firstIndex, short length.
|
// Same content, different firstIndex, short length.
|
||||||
a = freeLater(wrappedBuffer(new byte[] { 1, 2, 3 }).order(order));
|
a = releaseLater(wrappedBuffer(new byte[] { 1, 2, 3 }).order(order));
|
||||||
b = freeLater(wrappedBuffer(
|
b = releaseLater(wrappedBuffer(
|
||||||
wrappedBuffer(new byte[] { 0, 1, 2, 3, 4 }, 1, 2).order(order),
|
wrappedBuffer(new byte[] { 0, 1, 2, 3, 4 }, 1, 2).order(order),
|
||||||
wrappedBuffer(new byte[] { 0, 1, 2, 3, 4 }, 3, 1).order(order)));
|
wrappedBuffer(new byte[] { 0, 1, 2, 3, 4 }, 3, 1).order(order)));
|
||||||
assertTrue(ByteBufUtil.equals(a, b));
|
assertTrue(ByteBufUtil.equals(a, b));
|
||||||
|
|
||||||
// Different content, same firstIndex, short length.
|
// Different content, same firstIndex, short length.
|
||||||
a = freeLater(wrappedBuffer(new byte[] { 1, 2, 3 }).order(order));
|
a = releaseLater(wrappedBuffer(new byte[] { 1, 2, 3 }).order(order));
|
||||||
b = freeLater(wrappedBuffer(
|
b = releaseLater(wrappedBuffer(
|
||||||
wrappedBuffer(new byte[] { 1, 2 }).order(order),
|
wrappedBuffer(new byte[] { 1, 2 }).order(order),
|
||||||
wrappedBuffer(new byte[] { 4 }).order(order)));
|
wrappedBuffer(new byte[] { 4 }).order(order)));
|
||||||
assertFalse(ByteBufUtil.equals(a, b));
|
assertFalse(ByteBufUtil.equals(a, b));
|
||||||
|
|
||||||
// Different content, different firstIndex, short length.
|
// Different content, different firstIndex, short length.
|
||||||
a = freeLater(wrappedBuffer(new byte[] { 1, 2, 3 }).order(order));
|
a = releaseLater(wrappedBuffer(new byte[] { 1, 2, 3 }).order(order));
|
||||||
b = freeLater(wrappedBuffer(
|
b = releaseLater(wrappedBuffer(
|
||||||
wrappedBuffer(new byte[] { 0, 1, 2, 4, 5 }, 1, 2).order(order),
|
wrappedBuffer(new byte[] { 0, 1, 2, 4, 5 }, 1, 2).order(order),
|
||||||
wrappedBuffer(new byte[] { 0, 1, 2, 4, 5 }, 3, 1).order(order)));
|
wrappedBuffer(new byte[] { 0, 1, 2, 4, 5 }, 3, 1).order(order)));
|
||||||
assertFalse(ByteBufUtil.equals(a, b));
|
assertFalse(ByteBufUtil.equals(a, b));
|
||||||
|
|
||||||
// Same content, same firstIndex, long length.
|
// Same content, same firstIndex, long length.
|
||||||
a = freeLater(wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).order(order));
|
a = releaseLater(wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).order(order));
|
||||||
b = freeLater(wrappedBuffer(
|
b = releaseLater(wrappedBuffer(
|
||||||
wrappedBuffer(new byte[] { 1, 2, 3 }).order(order),
|
wrappedBuffer(new byte[] { 1, 2, 3 }).order(order),
|
||||||
wrappedBuffer(new byte[] { 4, 5, 6 }).order(order),
|
wrappedBuffer(new byte[] { 4, 5, 6 }).order(order),
|
||||||
wrappedBuffer(new byte[] { 7, 8, 9, 10 }).order(order)));
|
wrappedBuffer(new byte[] { 7, 8, 9, 10 }).order(order)));
|
||||||
assertTrue(ByteBufUtil.equals(a, b));
|
assertTrue(ByteBufUtil.equals(a, b));
|
||||||
|
|
||||||
// Same content, different firstIndex, long length.
|
// Same content, different firstIndex, long length.
|
||||||
a = freeLater(wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).order(order));
|
a = releaseLater(wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).order(order));
|
||||||
b = freeLater(wrappedBuffer(
|
b = releaseLater(wrappedBuffer(
|
||||||
wrappedBuffer(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 1, 5).order(order),
|
wrappedBuffer(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 1, 5).order(order),
|
||||||
wrappedBuffer(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 6, 5).order(order)));
|
wrappedBuffer(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 6, 5).order(order)));
|
||||||
assertTrue(ByteBufUtil.equals(a, b));
|
assertTrue(ByteBufUtil.equals(a, b));
|
||||||
|
|
||||||
// Different content, same firstIndex, long length.
|
// Different content, same firstIndex, long length.
|
||||||
a = freeLater(wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).order(order));
|
a = releaseLater(wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).order(order));
|
||||||
b = freeLater(wrappedBuffer(
|
b = releaseLater(wrappedBuffer(
|
||||||
wrappedBuffer(new byte[] { 1, 2, 3, 4, 6 }).order(order),
|
wrappedBuffer(new byte[] { 1, 2, 3, 4, 6 }).order(order),
|
||||||
wrappedBuffer(new byte[] { 7, 8, 5, 9, 10 }).order(order)));
|
wrappedBuffer(new byte[] { 7, 8, 5, 9, 10 }).order(order)));
|
||||||
assertFalse(ByteBufUtil.equals(a, b));
|
assertFalse(ByteBufUtil.equals(a, b));
|
||||||
|
|
||||||
// Different content, different firstIndex, long length.
|
// Different content, different firstIndex, long length.
|
||||||
a = freeLater(wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).order(order));
|
a = releaseLater(wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).order(order));
|
||||||
b = freeLater(wrappedBuffer(
|
b = releaseLater(wrappedBuffer(
|
||||||
wrappedBuffer(new byte[] { 0, 1, 2, 3, 4, 6, 7, 8, 5, 9, 10, 11 }, 1, 5).order(order),
|
wrappedBuffer(new byte[] { 0, 1, 2, 3, 4, 6, 7, 8, 5, 9, 10, 11 }, 1, 5).order(order),
|
||||||
wrappedBuffer(new byte[] { 0, 1, 2, 3, 4, 6, 7, 8, 5, 9, 10, 11 }, 6, 5).order(order)));
|
wrappedBuffer(new byte[] { 0, 1, 2, 3, 4, 6, 7, 8, 5, 9, 10, 11 }, 6, 5).order(order)));
|
||||||
assertFalse(ByteBufUtil.equals(a, b));
|
assertFalse(ByteBufUtil.equals(a, b));
|
||||||
@ -324,7 +325,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
wrappedBuffer(wrappedBuffer(new byte[] { 1, 2, 3 }).order(order)),
|
wrappedBuffer(wrappedBuffer(new byte[] { 1, 2, 3 }).order(order)),
|
||||||
freeLater(wrappedBuffer(wrappedBuffer(
|
releaseLater(wrappedBuffer(wrappedBuffer(
|
||||||
new byte[] { 1 },
|
new byte[] { 1 },
|
||||||
new byte[] { 2 },
|
new byte[] { 2 },
|
||||||
new byte[] { 3 }).order(order))));
|
new byte[] { 3 }).order(order))));
|
||||||
@ -337,7 +338,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
wrappedBuffer(wrappedBuffer(new byte[] { 1, 2, 3 }).order(order)),
|
wrappedBuffer(wrappedBuffer(new byte[] { 1, 2, 3 }).order(order)),
|
||||||
freeLater(wrappedBuffer(
|
releaseLater(wrappedBuffer(
|
||||||
wrappedBuffer(new byte[] { 1 }).order(order),
|
wrappedBuffer(new byte[] { 1 }).order(order),
|
||||||
wrappedBuffer(new byte[] { 2 }).order(order),
|
wrappedBuffer(new byte[] { 2 }).order(order),
|
||||||
wrappedBuffer(new byte[] { 3 }).order(order))));
|
wrappedBuffer(new byte[] { 3 }).order(order))));
|
||||||
@ -350,7 +351,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
wrappedBuffer(wrappedBuffer(new byte[] { 1, 2, 3 }).order(order)),
|
wrappedBuffer(wrappedBuffer(new byte[] { 1, 2, 3 }).order(order)),
|
||||||
freeLater(wrappedBuffer(wrappedBuffer(
|
releaseLater(wrappedBuffer(wrappedBuffer(
|
||||||
ByteBuffer.wrap(new byte[] { 1 }),
|
ByteBuffer.wrap(new byte[] { 1 }),
|
||||||
ByteBuffer.wrap(new byte[] { 2 }),
|
ByteBuffer.wrap(new byte[] { 2 }),
|
||||||
ByteBuffer.wrap(new byte[] { 3 })))));
|
ByteBuffer.wrap(new byte[] { 3 })))));
|
||||||
@ -387,7 +388,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
|
|
||||||
// Different content, same firstIndex, short length.
|
// Different content, same firstIndex, short length.
|
||||||
a = wrappedBuffer(new byte[] { 1, 2, 3 }).order(order);
|
a = wrappedBuffer(new byte[] { 1, 2, 3 }).order(order);
|
||||||
b = freeLater(wrappedBuffer(wrappedBuffer(new byte[] { 1, 2 }, new byte[1]).order(order)));
|
b = releaseLater(wrappedBuffer(wrappedBuffer(new byte[] { 1, 2 }, new byte[1]).order(order)));
|
||||||
// to enable writeBytes
|
// to enable writeBytes
|
||||||
b.writerIndex(b.writerIndex() - 1);
|
b.writerIndex(b.writerIndex() - 1);
|
||||||
b.writeBytes(wrappedBuffer(new byte[] { 4 }).order(order));
|
b.writeBytes(wrappedBuffer(new byte[] { 4 }).order(order));
|
||||||
@ -403,7 +404,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
|
|
||||||
// Same content, same firstIndex, long length.
|
// Same content, same firstIndex, long length.
|
||||||
a = wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).order(order);
|
a = wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).order(order);
|
||||||
b = freeLater(wrappedBuffer(wrappedBuffer(new byte[] { 1, 2, 3 }, new byte[7])).order(order));
|
b = releaseLater(wrappedBuffer(wrappedBuffer(new byte[] { 1, 2, 3 }, new byte[7])).order(order));
|
||||||
// to enable writeBytes
|
// to enable writeBytes
|
||||||
b.writerIndex(b.writerIndex() - 7);
|
b.writerIndex(b.writerIndex() - 7);
|
||||||
b.writeBytes(wrappedBuffer(new byte[] { 4, 5, 6 }).order(order));
|
b.writeBytes(wrappedBuffer(new byte[] { 4, 5, 6 }).order(order));
|
||||||
@ -420,7 +421,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
|
|
||||||
// Different content, same firstIndex, long length.
|
// Different content, same firstIndex, long length.
|
||||||
a = wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).order(order);
|
a = wrappedBuffer(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }).order(order);
|
||||||
b = freeLater(wrappedBuffer(wrappedBuffer(new byte[] { 1, 2, 3, 4, 6 }, new byte[5])).order(order));
|
b = releaseLater(wrappedBuffer(wrappedBuffer(new byte[] { 1, 2, 3, 4, 6 }, new byte[5])).order(order));
|
||||||
// to enable writeBytes
|
// to enable writeBytes
|
||||||
b.writerIndex(b.writerIndex() - 5);
|
b.writerIndex(b.writerIndex() - 5);
|
||||||
b.writeBytes(wrappedBuffer(new byte[] { 7, 8, 5, 9, 10 }).order(order));
|
b.writeBytes(wrappedBuffer(new byte[] { 7, 8, 5, 9, 10 }).order(order));
|
||||||
@ -437,7 +438,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyBuffer() {
|
public void testEmptyBuffer() {
|
||||||
ByteBuf b = freeLater(wrappedBuffer(new byte[]{1, 2}, new byte[]{3, 4}));
|
ByteBuf b = releaseLater(wrappedBuffer(new byte[]{1, 2}, new byte[]{3, 4}));
|
||||||
b.readBytes(new byte[4]);
|
b.readBytes(new byte[4]);
|
||||||
b.readBytes(EMPTY_BYTES);
|
b.readBytes(EMPTY_BYTES);
|
||||||
}
|
}
|
||||||
@ -445,7 +446,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
// Test for https://github.com/netty/netty/issues/1060
|
// Test for https://github.com/netty/netty/issues/1060
|
||||||
@Test
|
@Test
|
||||||
public void testReadWithEmptyCompositeBuffer() {
|
public void testReadWithEmptyCompositeBuffer() {
|
||||||
ByteBuf buf = freeLater(compositeBuffer());
|
ByteBuf buf = releaseLater(compositeBuffer());
|
||||||
int n = 65;
|
int n = 65;
|
||||||
for (int i = 0; i < n; i ++) {
|
for (int i = 0; i < n; i ++) {
|
||||||
buf.writeByte(1);
|
buf.writeByte(1);
|
||||||
@ -455,7 +456,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testComponentMustBeSlice() {
|
public void testComponentMustBeSlice() {
|
||||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
CompositeByteBuf buf = releaseLater(compositeBuffer());
|
||||||
buf.addComponent(buffer(4).setIndex(1, 3));
|
buf.addComponent(buffer(4).setIndex(1, 3));
|
||||||
assertThat(buf.component(0), is(instanceOf(SlicedByteBuf.class)));
|
assertThat(buf.component(0), is(instanceOf(SlicedByteBuf.class)));
|
||||||
assertThat(buf.component(0).capacity(), is(2));
|
assertThat(buf.component(0).capacity(), is(2));
|
||||||
@ -468,7 +469,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
ByteBuf c2 = buffer().writeByte(2).retain();
|
ByteBuf c2 = buffer().writeByte(2).retain();
|
||||||
ByteBuf c3 = buffer().writeByte(3).retain(2);
|
ByteBuf c3 = buffer().writeByte(3).retain(2);
|
||||||
|
|
||||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
CompositeByteBuf buf = releaseLater(compositeBuffer());
|
||||||
assertThat(buf.refCnt(), is(1));
|
assertThat(buf.refCnt(), is(1));
|
||||||
buf.addComponents(c1, c2, c3);
|
buf.addComponents(c1, c2, c3);
|
||||||
|
|
||||||
@ -529,7 +530,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
ByteBuf c2 = buffer().writeByte(2).retain();
|
ByteBuf c2 = buffer().writeByte(2).retain();
|
||||||
ByteBuf c3 = buffer().writeByte(3).retain(2);
|
ByteBuf c3 = buffer().writeByte(3).retain(2);
|
||||||
|
|
||||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
CompositeByteBuf buf = releaseLater(compositeBuffer());
|
||||||
assertThat(buf.refCnt(), is(1));
|
assertThat(buf.refCnt(), is(1));
|
||||||
|
|
||||||
List<ByteBuf> components = new ArrayList<ByteBuf>();
|
List<ByteBuf> components = new ArrayList<ByteBuf>();
|
||||||
@ -551,7 +552,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNestedLayout() {
|
public void testNestedLayout() {
|
||||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
CompositeByteBuf buf = releaseLater(compositeBuffer());
|
||||||
buf.addComponent(
|
buf.addComponent(
|
||||||
compositeBuffer()
|
compositeBuffer()
|
||||||
.addComponent(wrappedBuffer(new byte[]{1, 2}))
|
.addComponent(wrappedBuffer(new byte[]{1, 2}))
|
||||||
@ -567,7 +568,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRemoveLastComponent() {
|
public void testRemoveLastComponent() {
|
||||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
CompositeByteBuf buf = releaseLater(compositeBuffer());
|
||||||
buf.addComponent(wrappedBuffer(new byte[]{1, 2}));
|
buf.addComponent(wrappedBuffer(new byte[]{1, 2}));
|
||||||
assertEquals(1, buf.numComponents());
|
assertEquals(1, buf.numComponents());
|
||||||
buf.removeComponent(0);
|
buf.removeComponent(0);
|
||||||
@ -576,21 +577,21 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCopyEmpty() {
|
public void testCopyEmpty() {
|
||||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
CompositeByteBuf buf = releaseLater(compositeBuffer());
|
||||||
assertEquals(0, buf.numComponents());
|
assertEquals(0, buf.numComponents());
|
||||||
assertEquals(0, freeLater(buf.copy()).readableBytes());
|
assertEquals(0, releaseLater(buf.copy()).readableBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDuplicateEmpty() {
|
public void testDuplicateEmpty() {
|
||||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
CompositeByteBuf buf = releaseLater(compositeBuffer());
|
||||||
assertEquals(0, buf.numComponents());
|
assertEquals(0, buf.numComponents());
|
||||||
assertEquals(0, freeLater(buf.duplicate()).readableBytes());
|
assertEquals(0, releaseLater(buf.duplicate()).readableBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRemoveLastComponentWithOthersLeft() {
|
public void testRemoveLastComponentWithOthersLeft() {
|
||||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
CompositeByteBuf buf = releaseLater(compositeBuffer());
|
||||||
buf.addComponent(wrappedBuffer(new byte[]{1, 2}));
|
buf.addComponent(wrappedBuffer(new byte[]{1, 2}));
|
||||||
buf.addComponent(wrappedBuffer(new byte[]{1, 2}));
|
buf.addComponent(wrappedBuffer(new byte[]{1, 2}));
|
||||||
assertEquals(2, buf.numComponents());
|
assertEquals(2, buf.numComponents());
|
||||||
@ -632,7 +633,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void testGatheringWrites(ByteBuf buf1, ByteBuf buf2) throws Exception {
|
private static void testGatheringWrites(ByteBuf buf1, ByteBuf buf2) throws Exception {
|
||||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
CompositeByteBuf buf = releaseLater(compositeBuffer());
|
||||||
buf.addComponent(buf1.writeBytes(new byte[]{1, 2}));
|
buf.addComponent(buf1.writeBytes(new byte[]{1, 2}));
|
||||||
buf.addComponent(buf2.writeBytes(new byte[]{1, 2}));
|
buf.addComponent(buf2.writeBytes(new byte[]{1, 2}));
|
||||||
buf.writerIndex(3);
|
buf.writerIndex(3);
|
||||||
@ -714,7 +715,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void testGatheringWritesPartial(ByteBuf buf1, ByteBuf buf2, boolean slice) throws Exception {
|
private static void testGatheringWritesPartial(ByteBuf buf1, ByteBuf buf2, boolean slice) throws Exception {
|
||||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
CompositeByteBuf buf = releaseLater(compositeBuffer());
|
||||||
buf1.writeBytes(new byte[]{1, 2, 3, 4});
|
buf1.writeBytes(new byte[]{1, 2, 3, 4});
|
||||||
buf2.writeBytes(new byte[]{1, 2, 3, 4});
|
buf2.writeBytes(new byte[]{1, 2, 3, 4});
|
||||||
if (slice) {
|
if (slice) {
|
||||||
@ -757,7 +758,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void testGatheringWritesSingleBuf(ByteBuf buf1) throws Exception {
|
private static void testGatheringWritesSingleBuf(ByteBuf buf1) throws Exception {
|
||||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
CompositeByteBuf buf = releaseLater(compositeBuffer());
|
||||||
buf.addComponent(buf1.writeBytes(new byte[]{1, 2, 3, 4}));
|
buf.addComponent(buf1.writeBytes(new byte[]{1, 2, 3, 4}));
|
||||||
buf.writerIndex(3);
|
buf.writerIndex(3);
|
||||||
buf.readerIndex(1);
|
buf.readerIndex(1);
|
||||||
@ -778,7 +779,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testisDirectMultipleBufs() {
|
public void testisDirectMultipleBufs() {
|
||||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
CompositeByteBuf buf = releaseLater(compositeBuffer());
|
||||||
assertFalse(buf.isDirect());
|
assertFalse(buf.isDirect());
|
||||||
|
|
||||||
buf.addComponent(directBuffer().writeByte(1));
|
buf.addComponent(directBuffer().writeByte(1));
|
||||||
@ -794,7 +795,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
// See https://github.com/netty/netty/issues/1976
|
// See https://github.com/netty/netty/issues/1976
|
||||||
@Test
|
@Test
|
||||||
public void testDiscardSomeReadBytes() {
|
public void testDiscardSomeReadBytes() {
|
||||||
CompositeByteBuf cbuf = freeLater(compositeBuffer());
|
CompositeByteBuf cbuf = releaseLater(compositeBuffer());
|
||||||
int len = 8 * 4;
|
int len = 8 * 4;
|
||||||
for (int i = 0; i < len; i += 4) {
|
for (int i = 0; i < len; i += 4) {
|
||||||
ByteBuf buf = Unpooled.buffer().writeInt(i);
|
ByteBuf buf = Unpooled.buffer().writeInt(i);
|
||||||
|
@ -15,11 +15,26 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.util;
|
package io.netty.util;
|
||||||
|
|
||||||
|
import io.netty.util.concurrent.GlobalEventExecutor;
|
||||||
|
import io.netty.util.concurrent.ScheduledFuture;
|
||||||
|
import io.netty.util.internal.StringUtil;
|
||||||
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
|
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.IdentityHashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collection of method to handle objects that may implement {@link ReferenceCounted}.
|
* Collection of method to handle objects that may implement {@link ReferenceCounted}.
|
||||||
*/
|
*/
|
||||||
public final class ReferenceCountUtil {
|
public final class ReferenceCountUtil {
|
||||||
|
|
||||||
|
private static final InternalLogger logger = InternalLoggerFactory.getInstance(ReferenceCountUtil.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to call {@link ReferenceCounted#retain()} if the specified message implements {@link ReferenceCounted}.
|
* Try to call {@link ReferenceCounted#retain()} if the specified message implements {@link ReferenceCounted}.
|
||||||
* If the specified message doesn't implement {@link ReferenceCounted}, this method does nothing.
|
* If the specified message doesn't implement {@link ReferenceCounted}, this method does nothing.
|
||||||
@ -66,5 +81,102 @@ public final class ReferenceCountUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Map<Thread, List<Entry>> pendingReleases = new IdentityHashMap<Thread, List<Entry>>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules the specified object to be released when the caller thread terminates. Note that this operation is
|
||||||
|
* intended to simplify reference counting of ephemeral objects during unit tests. Do not use it beyond the
|
||||||
|
* intended use case.
|
||||||
|
*/
|
||||||
|
public static <T> T releaseLater(T msg) {
|
||||||
|
return releaseLater(msg, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules the specified object to be released when the caller thread terminates. Note that this operation is
|
||||||
|
* intended to simplify reference counting of ephemeral objects during unit tests. Do not use it beyond the
|
||||||
|
* intended use case.
|
||||||
|
*/
|
||||||
|
public static <T> T releaseLater(T msg, int decrement) {
|
||||||
|
if (msg instanceof ReferenceCounted) {
|
||||||
|
synchronized (pendingReleases) {
|
||||||
|
Thread thread = Thread.currentThread();
|
||||||
|
List<Entry> entries = pendingReleases.get(thread);
|
||||||
|
if (entries == null) {
|
||||||
|
// Start the periodic releasing task (if not started yet.)
|
||||||
|
if (pendingReleases.isEmpty()) {
|
||||||
|
ReleasingTask task = new ReleasingTask();
|
||||||
|
task.future = GlobalEventExecutor.INSTANCE.scheduleWithFixedDelay(task, 1, 1, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new entry.
|
||||||
|
entries = new ArrayList<Entry>();
|
||||||
|
pendingReleases.put(thread, entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
entries.add(new Entry((ReferenceCounted) msg, decrement));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class Entry {
|
||||||
|
final ReferenceCounted obj;
|
||||||
|
final int decrement;
|
||||||
|
|
||||||
|
Entry(ReferenceCounted obj, int decrement) {
|
||||||
|
this.obj = obj;
|
||||||
|
this.decrement = decrement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return StringUtil.simpleClassName(obj) + ".release(" + decrement + ") refCnt: " + obj.refCnt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases the objects when the thread that called {@link #releaseLater(Object)} has been terminated.
|
||||||
|
*/
|
||||||
|
private static final class ReleasingTask implements Runnable {
|
||||||
|
volatile ScheduledFuture<?> future;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
synchronized (pendingReleases) {
|
||||||
|
for (Iterator<Map.Entry<Thread, List<Entry>>> i = pendingReleases.entrySet().iterator();
|
||||||
|
i.hasNext();) {
|
||||||
|
|
||||||
|
Map.Entry<Thread, List<Entry>> e = i.next();
|
||||||
|
if (e.getKey().isAlive()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
releaseAll(e.getValue());
|
||||||
|
|
||||||
|
// Remove from the map since the thread is not alive anymore.
|
||||||
|
i.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pendingReleases.isEmpty()) {
|
||||||
|
future.cancel(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void releaseAll(Iterable<Entry> entries) {
|
||||||
|
for (Entry e: entries) {
|
||||||
|
try {
|
||||||
|
if (!e.obj.release(e.decrement)) {
|
||||||
|
logger.warn("Non-zero refCnt: {}", e);
|
||||||
|
} else {
|
||||||
|
logger.warn("Released: {}", e);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.warn("Failed to release an object: {}", e.obj, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ReferenceCountUtil() { }
|
private ReferenceCountUtil() { }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user