Ensure to release the component when it's removed from CompositeByteBuf / Add tests for reference counting of CompositeByteBuf
This commit is contained in:
parent
70eee55a48
commit
9e890f0ab8
@ -319,7 +319,6 @@ public class DefaultCompositeByteBuf extends AbstractReferenceCountedByteBuf
|
||||
}
|
||||
|
||||
private void updateComponentOffsets(int cIndex) {
|
||||
|
||||
Component c = components.get(cIndex);
|
||||
lastAccessed = c;
|
||||
lastAccessedId = cIndex;
|
||||
@ -341,7 +340,7 @@ public class DefaultCompositeByteBuf extends AbstractReferenceCountedByteBuf
|
||||
@Override
|
||||
public CompositeByteBuf removeComponent(int cIndex) {
|
||||
checkComponentIndex(cIndex);
|
||||
components.remove(cIndex);
|
||||
components.remove(cIndex).freeIfNecessary();
|
||||
updateComponentOffsets(cIndex);
|
||||
return this;
|
||||
}
|
||||
@ -349,7 +348,13 @@ public class DefaultCompositeByteBuf extends AbstractReferenceCountedByteBuf
|
||||
@Override
|
||||
public CompositeByteBuf removeComponents(int cIndex, int numComponents) {
|
||||
checkComponentIndex(cIndex, numComponents);
|
||||
components.subList(cIndex, cIndex + numComponents).clear();
|
||||
|
||||
List<Component> toRemove = components.subList(cIndex, cIndex + numComponents);
|
||||
for (Component c: toRemove) {
|
||||
c.freeIfNecessary();
|
||||
}
|
||||
toRemove.clear();
|
||||
|
||||
updateComponentOffsets(cIndex);
|
||||
return this;
|
||||
}
|
||||
|
@ -20,9 +20,11 @@ import org.junit.Test;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static io.netty.buffer.Unpooled.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
@ -430,4 +432,89 @@ public abstract class AbstractCompositeByteBufTest extends
|
||||
assertEquals(1, buf.readByte());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComponentMustBeSlice() {
|
||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
||||
buf.addComponent(buffer(4).setIndex(1, 3));
|
||||
assertThat(buf.component(0), is(instanceOf(SlicedByteBuf.class)));
|
||||
assertThat(buf.component(0).capacity(), is(2));
|
||||
assertThat(buf.component(0).maxCapacity(), is(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReferenceCounts1() {
|
||||
ByteBuf c1 = buffer().writeByte(1);
|
||||
ByteBuf c2 = buffer().writeByte(2).retain();
|
||||
ByteBuf c3 = buffer().writeByte(3).retain(2);
|
||||
|
||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
||||
assertThat(buf.refCnt(), is(1));
|
||||
buf.addComponents(c1, c2, c3);
|
||||
|
||||
assertThat(buf.refCnt(), is(1));
|
||||
|
||||
// Ensure that c[123]'s refCount did not change.
|
||||
assertThat(c1.refCnt(), is(1));
|
||||
assertThat(c2.refCnt(), is(2));
|
||||
assertThat(c3.refCnt(), is(3));
|
||||
|
||||
assertThat(buf.component(0).refCnt(), is(1));
|
||||
assertThat(buf.component(1).refCnt(), is(2));
|
||||
assertThat(buf.component(2).refCnt(), is(3));
|
||||
|
||||
c3.release(2);
|
||||
c2.release();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReferenceCounts2() {
|
||||
ByteBuf c1 = buffer().writeByte(1);
|
||||
ByteBuf c2 = buffer().writeByte(2).retain();
|
||||
ByteBuf c3 = buffer().writeByte(3).retain(2);
|
||||
|
||||
CompositeByteBuf bufA = freeLater(compositeBuffer());
|
||||
bufA.addComponents(c1, c2, c3);
|
||||
|
||||
CompositeByteBuf bufB = freeLater(compositeBuffer());
|
||||
bufB.addComponent(bufA);
|
||||
|
||||
// Ensure that bufA has been released.
|
||||
assertThat(bufA.refCnt(), is(0));
|
||||
|
||||
// Ensure that c[123]'s refCnt did not change.
|
||||
// Internally, it's:
|
||||
// 1) increased by 1 by addComponent(), and then
|
||||
// 2) decreased by 1 by bufA.release() which is called by addComponent().
|
||||
assertThat(c1.refCnt(), is(1));
|
||||
assertThat(c2.refCnt(), is(2));
|
||||
assertThat(c3.refCnt(), is(3));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReferenceCounts3() {
|
||||
ByteBuf c1 = buffer().writeByte(1);
|
||||
ByteBuf c2 = buffer().writeByte(2).retain();
|
||||
ByteBuf c3 = buffer().writeByte(3).retain(2);
|
||||
|
||||
CompositeByteBuf buf = freeLater(compositeBuffer());
|
||||
assertThat(buf.refCnt(), is(1));
|
||||
|
||||
List<ByteBuf> components = new ArrayList<ByteBuf>();
|
||||
Collections.addAll(components, c1, c2, c3);
|
||||
buf.addComponents(components);
|
||||
|
||||
// Ensure that c[123]'s refCount did not change.
|
||||
assertThat(c1.refCnt(), is(1));
|
||||
assertThat(c2.refCnt(), is(2));
|
||||
assertThat(c3.refCnt(), is(3));
|
||||
|
||||
assertThat(buf.component(0).refCnt(), is(1));
|
||||
assertThat(buf.component(1).refCnt(), is(2));
|
||||
assertThat(buf.component(2).refCnt(), is(3));
|
||||
|
||||
c3.release(2);
|
||||
c2.release();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user