Eliminate unnessary wrapping when call ByteBuf.asReadOnly() in some cases

Motivation:

We can eliminate unnessary wrapping when call ByteBuf.asReadOnly() in some cases to reduce indirection.

Modifications:

- Check if asReadOnly() needs to create a new instance or not
- Add test cases

Result:

Less object creation / wrapping.
This commit is contained in:
Norman Maurer 2017-02-13 15:27:40 +01:00
parent adcde84253
commit 371c0ca0f8
4 changed files with 39 additions and 12 deletions

View File

@ -412,4 +412,9 @@ public class ReadOnlyByteBuf extends AbstractDerivedByteBuf {
public ByteBuf capacity(int newCapacity) {
throw new ReadOnlyBufferException();
}
@Override
public ByteBuf asReadOnly() {
return this;
}
}

View File

@ -26,7 +26,7 @@ final class UnreleasableByteBuf extends WrappedByteBuf {
private SwappedByteBuf swappedBuf;
UnreleasableByteBuf(ByteBuf buf) {
super(buf);
super(buf instanceof UnreleasableByteBuf ? buf.unwrap() : buf);
}
@Override
@ -47,7 +47,7 @@ final class UnreleasableByteBuf extends WrappedByteBuf {
@Override
public ByteBuf asReadOnly() {
return new UnreleasableByteBuf(buf.asReadOnly());
return buf.isReadOnly() ? this : new UnreleasableByteBuf(buf.asReadOnly());
}
@Override

View File

@ -182,4 +182,13 @@ public class ReadOnlyByteBufTest {
public void shouldIndicteNotWritableAnyNumber() {
assertFalse(unmodifiableBuffer(buffer(1)).isWritable(1));
}
@Test
public void asReadOnly() {
ByteBuf buf = buffer(1);
ByteBuf readOnly = buf.asReadOnly();
assertTrue(readOnly.isReadOnly());
assertSame(readOnly, readOnly.asReadOnly());
readOnly.release();
}
}

View File

@ -15,27 +15,40 @@
*/
package io.netty.buffer;
import org.junit.Assert;
import org.junit.Test;
import static io.netty.buffer.Unpooled.buffer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
public class UnreleaseableByteBufTest {
@Test
public void testCantRelease() {
ByteBuf buf = Unpooled.unreleasableBuffer(Unpooled.copyInt(1));
Assert.assertEquals(1, buf.refCnt());
Assert.assertFalse(buf.release());
Assert.assertEquals(1, buf.refCnt());
Assert.assertFalse(buf.release());
Assert.assertEquals(1, buf.refCnt());
assertEquals(1, buf.refCnt());
assertFalse(buf.release());
assertEquals(1, buf.refCnt());
assertFalse(buf.release());
assertEquals(1, buf.refCnt());
buf.retain(5);
Assert.assertEquals(1, buf.refCnt());
assertEquals(1, buf.refCnt());
buf.retain();
Assert.assertEquals(1, buf.refCnt());
assertEquals(1, buf.refCnt());
Assert.assertTrue(buf.unwrap().release());
Assert.assertEquals(0, buf.refCnt());
assertTrue(buf.unwrap().release());
assertEquals(0, buf.refCnt());
}
@Test
public void testWrappedReadOnly() {
ByteBuf buf = Unpooled.unreleasableBuffer(buffer(1).asReadOnly());
assertSame(buf, buf.asReadOnly());
assertTrue(buf.unwrap().release());
}
}