Skip to content

Commit

Permalink
Split up the nioBuffers() method to allow for inline. Related to #1812
Browse files Browse the repository at this point in the history
This move less common method patterns to extra methods and so make the nioBuffers() method with most common pattern (backed by one ByteBuffer) small enough for inlining.
  • Loading branch information
Norman Maurer committed Sep 5, 2013
1 parent c97971b commit 92cec8d
Showing 1 changed file with 33 additions and 29 deletions.
62 changes: 33 additions & 29 deletions transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -315,12 +315,11 @@ public boolean remove(Throwable cause) {
* </p>
*/
public ByteBuffer[] nioBuffers() {
ByteBuffer[] nioBuffers = this.nioBuffers;
long nioBufferSize = 0;
int nioBufferCount = 0;

final int mask = buffer.length - 1;
final ByteBufAllocator alloc = channel.alloc();
ByteBuffer[] nioBuffers = this.nioBuffers;
Object m;
int i = flushed;
while (i != unflushed && (m = buffer[i].msg) != null) {
Expand All @@ -331,53 +330,58 @@ public ByteBuffer[] nioBuffers() {
}

ByteBuf buf = (ByteBuf) m;

final int readerIndex = buf.readerIndex();
final int readableBytes = buf.writerIndex() - readerIndex;

if (readableBytes > 0) {
nioBufferSize += readableBytes;

int count = buf.nioBufferCount();
if (nioBufferCount + count > nioBuffers.length) {
this.nioBuffers = nioBuffers = doubleNioBufferArray(nioBuffers, nioBufferCount);
}
if (buf.isDirect() || !alloc.isDirectBufferPooled()) {
int count = buf.nioBufferCount();
if (count == 1) {
if (nioBufferCount == nioBuffers.length) {
this.nioBuffers = nioBuffers = doubleNioBufferArray(nioBuffers, nioBufferCount);
}
if (buf.nioBufferCount() == 1) {
nioBuffers[nioBufferCount ++] = buf.internalNioBuffer(readerIndex, readableBytes);
} else {
ByteBuffer[] nioBufs = buf.nioBuffers();
if (nioBufferCount + nioBufs.length > nioBuffers.length) {
this.nioBuffers = nioBuffers = doubleNioBufferArray(nioBuffers, nioBufferCount);
}
for (ByteBuffer nioBuf: nioBufs) {
if (nioBuf == null) {
break;
}
nioBuffers[nioBufferCount ++] = nioBuf;
}
nioBufferCount = fillBufferArray(buf, nioBuffers, nioBufferCount);
}
} else {
ByteBuf directBuf = alloc.directBuffer(readableBytes);
directBuf.writeBytes(buf, readerIndex, readableBytes);
buf.release();
buffer[i].msg = directBuf;
if (nioBufferCount == nioBuffers.length) {
nioBuffers = doubleNioBufferArray(nioBuffers, nioBufferCount);
}
nioBuffers[nioBufferCount ++] = directBuf.internalNioBuffer(0, readableBytes);
nioBufferCount = fillBufferArrayNonDirect(buffer[i], buf, readerIndex,
readableBytes, alloc, nioBuffers, nioBufferCount);
}
}

i = i + 1 & mask;
}

this.nioBufferCount = nioBufferCount;
this.nioBufferSize = nioBufferSize;

return nioBuffers;
}

private static int fillBufferArray(ByteBuf buf, ByteBuffer[] nioBuffers, int nioBufferCount) {
ByteBuffer[] nioBufs = buf.nioBuffers();
for (ByteBuffer nioBuf: nioBufs) {
if (nioBuf == null) {
break;
}
nioBuffers[nioBufferCount ++] = nioBuf;
}
return nioBufferCount;
}

private static int fillBufferArrayNonDirect(Entry entry, ByteBuf buf, int readerIndex, int readableBytes,
ByteBufAllocator alloc, ByteBuffer[] nioBuffers, int nioBufferCount) {
ByteBuf directBuf = alloc.directBuffer(readableBytes);
directBuf.writeBytes(buf, readerIndex, readableBytes);
buf.release();
entry.msg = directBuf;
if (nioBufferCount == nioBuffers.length) {
nioBuffers = doubleNioBufferArray(nioBuffers, nioBufferCount);
}
nioBuffers[nioBufferCount ++] = directBuf.internalNioBuffer(0, readableBytes);
return nioBufferCount;
}

private static ByteBuffer[] doubleNioBufferArray(ByteBuffer[] array, int size) {
int newCapacity = array.length << 1;
if (newCapacity < 0) {
Expand Down

0 comments on commit 92cec8d

Please sign in to comment.