From 972620d4311715488104a98b191f1ac8ace8afaa Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Fri, 16 Oct 2009 04:31:33 +0000 Subject: [PATCH] Resolved issue: NETTY-241 Add more ChannelBufferFactory.getBuffer() methods for less memory bandwidth consumption --- .../buffer/AbstractChannelBufferFactory.java | 4 ++ .../netty/buffer/ChannelBufferFactory.java | 49 +++++++++++++++++++ .../buffer/DirectChannelBufferFactory.java | 32 ++++++++++++ .../buffer/HeapChannelBufferFactory.java | 17 +++++++ 4 files changed, 102 insertions(+) diff --git a/src/main/java/org/jboss/netty/buffer/AbstractChannelBufferFactory.java b/src/main/java/org/jboss/netty/buffer/AbstractChannelBufferFactory.java index 8215b9e69b..3f1ff5dedf 100644 --- a/src/main/java/org/jboss/netty/buffer/AbstractChannelBufferFactory.java +++ b/src/main/java/org/jboss/netty/buffer/AbstractChannelBufferFactory.java @@ -53,6 +53,10 @@ public abstract class AbstractChannelBufferFactory implements ChannelBufferFacto return getBuffer(getDefaultOrder(), capacity); } + public ChannelBuffer getBuffer(byte[] array, int offset, int length) { + return getBuffer(getDefaultOrder(), array, offset, length); + } + public ByteOrder getDefaultOrder() { return defaultOrder; } diff --git a/src/main/java/org/jboss/netty/buffer/ChannelBufferFactory.java b/src/main/java/org/jboss/netty/buffer/ChannelBufferFactory.java index 939f2a8e66..c0c1ca345e 100644 --- a/src/main/java/org/jboss/netty/buffer/ChannelBufferFactory.java +++ b/src/main/java/org/jboss/netty/buffer/ChannelBufferFactory.java @@ -15,6 +15,7 @@ */ package org.jboss.netty.buffer; +import java.nio.ByteBuffer; import java.nio.ByteOrder; /** @@ -48,6 +49,54 @@ public interface ChannelBufferFactory { */ ChannelBuffer getBuffer(ByteOrder endianness, int capacity); + /** + * Returns a {@link ChannelBuffer} whose content is equals to the sub-region + * of the specified {@code array}. Depending on the factory implementation, + * the returned buffer could wrap the {@code array} or create a new copy of + * the {@code array}. + * This method is identical to {@code getBuffer(getDefaultOrder(), array, offset, length)}. + * + * @param array the byte array + * @param offset the offset of the byte array + * @param length the length of the byte array + * + * @return a {@link ChannelBuffer} with the specified content, + * whose {@code readerIndex} and {@code writerIndex} + * are {@code 0} and {@code (length - offset)} respectively + */ + ChannelBuffer getBuffer(byte[] array, int offset, int length); + + /** + * Returns a {@link ChannelBuffer} whose content is equals to the sub-region + * of the specified {@code array}. Depending on the factory implementation, + * the returned buffer could wrap the {@code array} or create a new copy of + * the {@code array}. + * + * @param endianness the endianness of the returned {@link ChannelBuffer} + * @param array the byte array + * @param offset the offset of the byte array + * @param length the length of the byte array + * + * @return a {@link ChannelBuffer} with the specified content, + * whose {@code readerIndex} and {@code writerIndex} + * are {@code 0} and {@code (length - offset)} respectively + */ + ChannelBuffer getBuffer(ByteOrder endianness, byte[] array, int offset, int length); + + /** + * Returns a {@link ChannelBuffer} whose content is equals to the sub-region + * of the specified {@code nioBuffer}. Depending on the factory + * implementation, the returned buffer could wrap the {@code nioBuffer} or + * create a new copy of the {@code nioBuffer}. + * + * @param nioBuffer the NIO {@link ByteBuffer} + * + * @return a {@link ChannelBuffer} with the specified content, + * whose {@code readerIndex} and {@code writerIndex} + * are {@code 0} and {@code nioBuffer.remaining()} respectively + */ + ChannelBuffer getBuffer(ByteBuffer nioBuffer); + /** * Returns the default endianness of the {@link ChannelBuffer} which is * returned by {@link #getBuffer(int)}. diff --git a/src/main/java/org/jboss/netty/buffer/DirectChannelBufferFactory.java b/src/main/java/org/jboss/netty/buffer/DirectChannelBufferFactory.java index 543fe68806..bf09abfdbc 100644 --- a/src/main/java/org/jboss/netty/buffer/DirectChannelBufferFactory.java +++ b/src/main/java/org/jboss/netty/buffer/DirectChannelBufferFactory.java @@ -16,6 +16,7 @@ package org.jboss.netty.buffer; import java.lang.ref.ReferenceQueue; +import java.nio.ByteBuffer; import java.nio.ByteOrder; /** @@ -129,6 +130,37 @@ public class DirectChannelBufferFactory extends AbstractChannelBufferFactory { return slice; } + public ChannelBuffer getBuffer(ByteOrder order, byte[] array, int offset, int length) { + if (array == null) { + throw new NullPointerException("array"); + } + if (offset < 0) { + throw new IndexOutOfBoundsException("offset: " + offset); + } + if (length == 0) { + return ChannelBuffers.EMPTY_BUFFER; + } + if (offset + length > array.length) { + throw new IndexOutOfBoundsException("length: " + length); + } + + ChannelBuffer buf = getBuffer(order, length); + buf.writeBytes(array, offset, length); + return buf; + } + + public ChannelBuffer getBuffer(ByteBuffer nioBuffer) { + if (nioBuffer.isDirect()) { + return ChannelBuffers.wrappedBuffer(nioBuffer); + } + + ChannelBuffer buf = getBuffer(nioBuffer.order(), nioBuffer.remaining()); + int pos = nioBuffer.position(); + buf.writeBytes(nioBuffer); + nioBuffer.position(pos); + return buf; + } + private ChannelBuffer allocateBigEndianBuffer(int capacity) { ChannelBuffer slice; synchronized (bigEndianLock) { diff --git a/src/main/java/org/jboss/netty/buffer/HeapChannelBufferFactory.java b/src/main/java/org/jboss/netty/buffer/HeapChannelBufferFactory.java index 87d3b3249f..6bde96b28e 100644 --- a/src/main/java/org/jboss/netty/buffer/HeapChannelBufferFactory.java +++ b/src/main/java/org/jboss/netty/buffer/HeapChannelBufferFactory.java @@ -15,6 +15,7 @@ */ package org.jboss.netty.buffer; +import java.nio.ByteBuffer; import java.nio.ByteOrder; /** @@ -71,4 +72,20 @@ public class HeapChannelBufferFactory extends AbstractChannelBufferFactory { public ChannelBuffer getBuffer(ByteOrder order, int capacity) { return ChannelBuffers.buffer(order, capacity); } + + public ChannelBuffer getBuffer(ByteOrder order, byte[] array, int offset, int length) { + return ChannelBuffers.wrappedBuffer(order, array, offset, length); + } + + public ChannelBuffer getBuffer(ByteBuffer nioBuffer) { + if (!nioBuffer.isReadOnly() && nioBuffer.hasArray()) { + return ChannelBuffers.wrappedBuffer(nioBuffer); + } + + ChannelBuffer buf = getBuffer(nioBuffer.order(), nioBuffer.remaining()); + int pos = nioBuffer.position(); + buf.writeBytes(nioBuffer); + nioBuffer.position(pos); + return buf; + } }