Always use EmptyByteBuf when a user attempts to construct a buffer with 0 maxCapacity / Make EmptyByteBuf remember the allocator it came from / Optimize EmptyByteBuf a little bit
This commit is contained in:
parent
096e4c95ef
commit
63116239ac
@ -41,7 +41,7 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
|
|||||||
*/
|
*/
|
||||||
protected AbstractByteBufAllocator(boolean preferDirect) {
|
protected AbstractByteBufAllocator(boolean preferDirect) {
|
||||||
directByDefault = preferDirect && PlatformDependent.hasUnsafe();
|
directByDefault = preferDirect && PlatformDependent.hasUnsafe();
|
||||||
emptyBuf = new UnpooledHeapByteBuf(this, 0, 0);
|
emptyBuf = new EmptyByteBuf(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -27,29 +27,44 @@ import java.nio.channels.GatheringByteChannel;
|
|||||||
import java.nio.channels.ScatteringByteChannel;
|
import java.nio.channels.ScatteringByteChannel;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An empty {@link ByteBuf} whose capacity and maximum capacity are all {@code 0}.
|
||||||
|
*/
|
||||||
public final class EmptyByteBuf implements ByteBuf {
|
public final class EmptyByteBuf implements ByteBuf {
|
||||||
|
|
||||||
private static final byte[] EMPTY_ARRAY = new byte[0];
|
private static final byte[] EMPTY_ARRAY = new byte[0];
|
||||||
|
private static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.allocateDirect(0);
|
||||||
|
private static final long EMPTY_BYTE_BUFFER_ADDRESS;
|
||||||
|
|
||||||
public static final EmptyByteBuf INSTANCE_BE = new EmptyByteBuf(ByteOrder.BIG_ENDIAN);
|
static {
|
||||||
public static final EmptyByteBuf INSTANCE_LE = new EmptyByteBuf(ByteOrder.LITTLE_ENDIAN);
|
long emptyByteBufferAddress = 0;
|
||||||
|
try {
|
||||||
private final ByteOrder order;
|
|
||||||
private final ByteBuffer nioBuf = ByteBuffer.allocateDirect(0);
|
|
||||||
private final long memoryAddress;
|
|
||||||
private final byte[] array = EMPTY_ARRAY;
|
|
||||||
private final String str;
|
|
||||||
|
|
||||||
private EmptyByteBuf(ByteOrder order) {
|
|
||||||
this.order = order;
|
|
||||||
nioBuf.order(order);
|
|
||||||
str = getClass().getSimpleName() + (order == ByteOrder.BIG_ENDIAN? "BE" : "LE");
|
|
||||||
|
|
||||||
if (PlatformDependent.hasUnsafe()) {
|
if (PlatformDependent.hasUnsafe()) {
|
||||||
memoryAddress = PlatformDependent.directBufferAddress(nioBuf);
|
emptyByteBufferAddress = PlatformDependent.directBufferAddress(EMPTY_BYTE_BUFFER);
|
||||||
} else {
|
|
||||||
memoryAddress = -1;
|
|
||||||
}
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
EMPTY_BYTE_BUFFER_ADDRESS = emptyByteBufferAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ByteBufAllocator alloc;
|
||||||
|
private final ByteOrder order;
|
||||||
|
private final String str;
|
||||||
|
private EmptyByteBuf swapped;
|
||||||
|
|
||||||
|
public EmptyByteBuf(ByteBufAllocator alloc) {
|
||||||
|
this(alloc, ByteOrder.BIG_ENDIAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
private EmptyByteBuf(ByteBufAllocator alloc, ByteOrder order) {
|
||||||
|
if (alloc == null) {
|
||||||
|
throw new NullPointerException("alloc");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.alloc = alloc;
|
||||||
|
this.order = order;
|
||||||
|
str = getClass().getSimpleName() + (order == ByteOrder.BIG_ENDIAN? "BE" : "LE");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -64,7 +79,7 @@ public final class EmptyByteBuf implements ByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBufAllocator alloc() {
|
public ByteBufAllocator alloc() {
|
||||||
return UnpooledByteBufAllocator.DEFAULT;
|
return alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -79,7 +94,7 @@ public final class EmptyByteBuf implements ByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDirect() {
|
public boolean isDirect() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -92,11 +107,17 @@ public final class EmptyByteBuf implements ByteBuf {
|
|||||||
if (endianness == null) {
|
if (endianness == null) {
|
||||||
throw new NullPointerException("endianness");
|
throw new NullPointerException("endianness");
|
||||||
}
|
}
|
||||||
if (endianness == ByteOrder.BIG_ENDIAN) {
|
if (endianness == order()) {
|
||||||
return INSTANCE_BE;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
return INSTANCE_LE;
|
EmptyByteBuf swapped = this.swapped;
|
||||||
|
if (swapped != null) {
|
||||||
|
return swapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.swapped = swapped = new EmptyByteBuf(alloc(), endianness);
|
||||||
|
return swapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -719,24 +740,24 @@ public final class EmptyByteBuf implements ByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer nioBuffer() {
|
public ByteBuffer nioBuffer() {
|
||||||
return nioBuf;
|
return EMPTY_BYTE_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer nioBuffer(int index, int length) {
|
public ByteBuffer nioBuffer(int index, int length) {
|
||||||
checkIndex(index, length);
|
checkIndex(index, length);
|
||||||
return nioBuf;
|
return nioBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer[] nioBuffers() {
|
public ByteBuffer[] nioBuffers() {
|
||||||
return new ByteBuffer[] { nioBuf };
|
return new ByteBuffer[] { EMPTY_BYTE_BUFFER };
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer[] nioBuffers(int index, int length) {
|
public ByteBuffer[] nioBuffers(int index, int length) {
|
||||||
checkIndex(index, length);
|
checkIndex(index, length);
|
||||||
return new ByteBuffer[] { nioBuf };
|
return nioBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -746,7 +767,7 @@ public final class EmptyByteBuf implements ByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] array() {
|
public byte[] array() {
|
||||||
return array;
|
return EMPTY_ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -756,13 +777,13 @@ public final class EmptyByteBuf implements ByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasMemoryAddress() {
|
public boolean hasMemoryAddress() {
|
||||||
return memoryAddress != -1;
|
return EMPTY_BYTE_BUFFER_ADDRESS != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long memoryAddress() {
|
public long memoryAddress() {
|
||||||
if (hasMemoryAddress()) {
|
if (hasMemoryAddress()) {
|
||||||
return memoryAddress;
|
return EMPTY_BYTE_BUFFER_ADDRESS;
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
@ -776,7 +797,7 @@ public final class EmptyByteBuf implements ByteBuf {
|
|||||||
@Override
|
@Override
|
||||||
public String toString(int index, int length, Charset charset) {
|
public String toString(int index, int length, Charset charset) {
|
||||||
checkIndex(index, length);
|
checkIndex(index, length);
|
||||||
return "";
|
return toString(charset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -92,7 +92,7 @@ public final class Unpooled {
|
|||||||
/**
|
/**
|
||||||
* A buffer whose capacity is {@code 0}.
|
* A buffer whose capacity is {@code 0}.
|
||||||
*/
|
*/
|
||||||
public static final ByteBuf EMPTY_BUFFER = EmptyByteBuf.INSTANCE_BE;
|
public static final ByteBuf EMPTY_BUFFER = ALLOC.buffer(0, 0);
|
||||||
|
|
||||||
public static <T> MessageBuf<T> messageBuffer() {
|
public static <T> MessageBuf<T> messageBuffer() {
|
||||||
return new DefaultMessageBuf<T>();
|
return new DefaultMessageBuf<T>();
|
||||||
|
Loading…
Reference in New Issue
Block a user