diff --git a/src/main/java/org/jboss/netty/channel/AdaptiveReceiveBufferSizePredictor.java b/src/main/java/org/jboss/netty/channel/AdaptiveReceiveBufferSizePredictor.java index 53426ec060..1d148e609d 100644 --- a/src/main/java/org/jboss/netty/channel/AdaptiveReceiveBufferSizePredictor.java +++ b/src/main/java/org/jboss/netty/channel/AdaptiveReceiveBufferSizePredictor.java @@ -37,8 +37,9 @@ import java.util.List; public class AdaptiveReceiveBufferSizePredictor implements ReceiveBufferSizePredictor { - // FIXME There's no easy way to configure receiveBufferSizePredictor - // via Bootstrap.setOption() because it works for only one channel. + static final int DEFAULT_MINIMUM = 64; + static final int DEFAULT_INITIAL = 1024; + static final int DEFAULT_MAXIMUM = 65536; private static final int INDEX_INCREMENT = 4; private static final int INDEX_DECREMENT = 1; @@ -97,10 +98,6 @@ public class AdaptiveReceiveBufferSizePredictor implements throw new Error("shouldn't reach here; please file a bug report."); } - private static final int DEFAULT_MINIMUM = 64; - private static final int DEFAULT_INITIAL = 1024; - private static final int DEFAULT_MAXIMUM = 65536; - private final int minIndex; private final int maxIndex; private int index; diff --git a/src/main/java/org/jboss/netty/channel/AdaptiveReceiveBufferSizePredictorFactory.java b/src/main/java/org/jboss/netty/channel/AdaptiveReceiveBufferSizePredictorFactory.java new file mode 100644 index 0000000000..e67c5d91e9 --- /dev/null +++ b/src/main/java/org/jboss/netty/channel/AdaptiveReceiveBufferSizePredictorFactory.java @@ -0,0 +1,72 @@ +/* + * Copyright 2009 Red Hat, Inc. + * + * Red Hat licenses this file to you under the Apache License, version 2.0 + * (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.channel; + + +/** + * The {@link ReceiveBufferSizePredictorFactory} that creates a new + * {@link AdaptiveReceiveBufferSizePredictor}. + * + * @author The Netty Project (netty-dev@lists.jboss.org) + * @author Trustin Lee (trustin@gmail.com) + * + * @version $Rev$, $Date$ + */ +public class AdaptiveReceiveBufferSizePredictorFactory implements + ReceiveBufferSizePredictorFactory { + + private final int minimum; + private final int initial; + private final int maximum; + + /** + * Creates a new factory with the default parameters. With the default + * parameters, the expected buffer size starts from {@code 1024}, does not + * go down below {@code 64}, and does not go up above {@code 65536}. + */ + public AdaptiveReceiveBufferSizePredictorFactory() { + this(AdaptiveReceiveBufferSizePredictor.DEFAULT_MINIMUM, + AdaptiveReceiveBufferSizePredictor.DEFAULT_INITIAL, + AdaptiveReceiveBufferSizePredictor.DEFAULT_MAXIMUM); + } + + /** + * Creates a new factory with the specified parameters. + * + * @param minimum the inclusive lower bound of the expected buffer size + * @param initial the initial buffer size when no feed back was received + * @param maximum the inclusive upper bound of the expected buffer size + */ + public AdaptiveReceiveBufferSizePredictorFactory(int minimum, int initial, int maximum) { + if (minimum <= 0) { + throw new IllegalArgumentException("minimum: " + minimum); + } + if (initial < minimum) { + throw new IllegalArgumentException("initial: " + initial); + } + if (maximum < initial) { + throw new IllegalArgumentException("maximum: " + maximum); + } + + this.minimum = minimum; + this.initial = initial; + this.maximum = maximum; + } + + public ReceiveBufferSizePredictor getPredictor() throws Exception { + return new AdaptiveReceiveBufferSizePredictor(minimum, initial, maximum); + } +} diff --git a/src/main/java/org/jboss/netty/channel/FixedReceiveBufferSizePredictorFactory.java b/src/main/java/org/jboss/netty/channel/FixedReceiveBufferSizePredictorFactory.java new file mode 100644 index 0000000000..fb2bfd1299 --- /dev/null +++ b/src/main/java/org/jboss/netty/channel/FixedReceiveBufferSizePredictorFactory.java @@ -0,0 +1,44 @@ +/* + * Copyright 2009 Red Hat, Inc. + * + * Red Hat licenses this file to you under the Apache License, version 2.0 + * (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.channel; + + +/** + * The {@link ReceiveBufferSizePredictorFactory} that returns a + * {@link FixedReceiveBufferSizePredictor} with the pre-defined configuration. + * + * @author The Netty Project (netty-dev@lists.jboss.org) + * @author Trustin Lee (trustin@gmail.com) + * + * @version $Rev$, $Date$ + */ +public class FixedReceiveBufferSizePredictorFactory implements + ReceiveBufferSizePredictorFactory { + + private final ReceiveBufferSizePredictor predictor; + + /** + * Creates a new factory that returns a {@link FixedReceiveBufferSizePredictor} + * which always returns the same prediction of the specified buffer size. + */ + public FixedReceiveBufferSizePredictorFactory(int bufferSize) { + predictor = new FixedReceiveBufferSizePredictor(bufferSize); + } + + public ReceiveBufferSizePredictor getPredictor() throws Exception { + return predictor; + } +} diff --git a/src/main/java/org/jboss/netty/channel/ReceiveBufferSizePredictorFactory.java b/src/main/java/org/jboss/netty/channel/ReceiveBufferSizePredictorFactory.java new file mode 100644 index 0000000000..3a0a3f1b27 --- /dev/null +++ b/src/main/java/org/jboss/netty/channel/ReceiveBufferSizePredictorFactory.java @@ -0,0 +1,32 @@ +/* + * Copyright 2009 Red Hat, Inc. + * + * Red Hat licenses this file to you under the Apache License, version 2.0 + * (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.channel; + +/** + * Creates a new {@link ReceiveBufferSizePredictor}. + * + * @author The Netty Project (netty-dev@lists.jboss.org) + * @author Trustin Lee (trustin@gmail.com) + * + * @version $Rev$, $Date$ + */ +public interface ReceiveBufferSizePredictorFactory { + + /** + * Returns a newly created {@link ReceiveBufferSizePredictor}. + */ + ReceiveBufferSizePredictor getPredictor() throws Exception; +} diff --git a/src/main/java/org/jboss/netty/channel/socket/DatagramChannelConfig.java b/src/main/java/org/jboss/netty/channel/socket/DatagramChannelConfig.java index 77cc17b75d..30a9148195 100644 --- a/src/main/java/org/jboss/netty/channel/socket/DatagramChannelConfig.java +++ b/src/main/java/org/jboss/netty/channel/socket/DatagramChannelConfig.java @@ -21,7 +21,9 @@ import java.net.NetworkInterface; import org.jboss.netty.channel.ChannelConfig; import org.jboss.netty.channel.FixedReceiveBufferSizePredictor; +import org.jboss.netty.channel.FixedReceiveBufferSizePredictorFactory; import org.jboss.netty.channel.ReceiveBufferSizePredictor; +import org.jboss.netty.channel.ReceiveBufferSizePredictorFactory; /** * A {@link ChannelConfig} for a {@link DatagramChannel}. @@ -49,6 +51,8 @@ import org.jboss.netty.channel.ReceiveBufferSizePredictor; * * {@code "receiveBufferSizePredictor"}{@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} * + * {@code "receiveBufferSizePredictorFactory"}{@link #setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory)} + * * {@code "sendBufferSize"}{@link #setSendBufferSize(int)} * * {@code "timeToLive"}{@link #setTimeToLive(int)} @@ -176,4 +180,24 @@ public interface DatagramChannelConfig extends ChannelConfig { * predictor is {@link FixedReceiveBufferSizePredictor}(768). */ void setReceiveBufferSizePredictor(ReceiveBufferSizePredictor predictor); + + /** + * Returns the {@link ReceiveBufferSizePredictorFactory} which creates a new + * {@link ReceiveBufferSizePredictor} when a new channel is created and + * no {@link ReceiveBufferSizePredictor} was set. If no predictor was set + * for the channel, {@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} + * will be called with the new predictor. The default factory is + * {@link FixedReceiveBufferSizePredictorFactory}(768). + */ + ReceiveBufferSizePredictorFactory getReceiveBufferSizePredictorFactory(); + + /** + * Sets the {@link ReceiveBufferSizePredictor} which creates a new + * {@link ReceiveBufferSizePredictor} when a new channel is created and + * no {@link ReceiveBufferSizePredictor} was set. If no predictor was set + * for the channel, {@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} + * will be called with the new predictor. The default factory is + * {@link FixedReceiveBufferSizePredictorFactory}(768). + */ + void setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory predictorFactory); } diff --git a/src/main/java/org/jboss/netty/channel/socket/DefaultDatagramChannelConfig.java b/src/main/java/org/jboss/netty/channel/socket/DefaultDatagramChannelConfig.java index a2ae4a7d85..6fccc8bd2f 100644 --- a/src/main/java/org/jboss/netty/channel/socket/DefaultDatagramChannelConfig.java +++ b/src/main/java/org/jboss/netty/channel/socket/DefaultDatagramChannelConfig.java @@ -24,8 +24,9 @@ import java.net.SocketException; import org.jboss.netty.channel.ChannelException; import org.jboss.netty.channel.DefaultChannelConfig; -import org.jboss.netty.channel.FixedReceiveBufferSizePredictor; +import org.jboss.netty.channel.FixedReceiveBufferSizePredictorFactory; import org.jboss.netty.channel.ReceiveBufferSizePredictor; +import org.jboss.netty.channel.ReceiveBufferSizePredictorFactory; import org.jboss.netty.util.internal.ConversionUtil; /** @@ -40,9 +41,12 @@ import org.jboss.netty.util.internal.ConversionUtil; public class DefaultDatagramChannelConfig extends DefaultChannelConfig implements DatagramChannelConfig { + private static final ReceiveBufferSizePredictorFactory DEFAULT_PREDICTOR_FACTORY = + new FixedReceiveBufferSizePredictorFactory(768); + private final DatagramSocket socket; - private volatile ReceiveBufferSizePredictor predictor = - new FixedReceiveBufferSizePredictor(768); + private volatile ReceiveBufferSizePredictor predictor; + private volatile ReceiveBufferSizePredictorFactory predictorFactory = DEFAULT_PREDICTOR_FACTORY; /** * Creates a new instance. @@ -263,13 +267,36 @@ public class DefaultDatagramChannelConfig extends DefaultChannelConfig } public ReceiveBufferSizePredictor getReceiveBufferSizePredictor() { + ReceiveBufferSizePredictor predictor = this.predictor; + if (predictor == null) { + try { + this.predictor = predictor = getReceiveBufferSizePredictorFactory().getPredictor(); + } catch (Exception e) { + throw new ChannelException( + "Failed to create a new " + + ReceiveBufferSizePredictor.class.getSimpleName() + '.', + e); + } + } return predictor; } - public void setReceiveBufferSizePredictor(ReceiveBufferSizePredictor predictor) { + public void setReceiveBufferSizePredictor( + ReceiveBufferSizePredictor predictor) { if (predictor == null) { throw new NullPointerException("predictor"); } this.predictor = predictor; } + + public ReceiveBufferSizePredictorFactory getReceiveBufferSizePredictorFactory() { + return predictorFactory; + } + + public void setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory predictorFactory) { + if (predictorFactory == null) { + throw new NullPointerException("predictorFactory"); + } + this.predictorFactory = predictorFactory; + } } diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/DefaultNioSocketChannelConfig.java b/src/main/java/org/jboss/netty/channel/socket/nio/DefaultNioSocketChannelConfig.java index 10bc04bd08..1447ae792d 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/DefaultNioSocketChannelConfig.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/DefaultNioSocketChannelConfig.java @@ -18,8 +18,10 @@ package org.jboss.netty.channel.socket.nio; import java.net.Socket; import java.util.Map; -import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictor; +import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictorFactory; +import org.jboss.netty.channel.ChannelException; import org.jboss.netty.channel.ReceiveBufferSizePredictor; +import org.jboss.netty.channel.ReceiveBufferSizePredictorFactory; import org.jboss.netty.channel.socket.DefaultSocketChannelConfig; import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLoggerFactory; @@ -40,10 +42,13 @@ class DefaultNioSocketChannelConfig extends DefaultSocketChannelConfig private static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultNioSocketChannelConfig.class); + private static final ReceiveBufferSizePredictorFactory DEFAULT_PREDICTOR_FACTORY = + new AdaptiveReceiveBufferSizePredictorFactory(); + private volatile int writeBufferHighWaterMark = 64 * 1024; private volatile int writeBufferLowWaterMark = 32 * 1024; - private volatile ReceiveBufferSizePredictor predictor = - new AdaptiveReceiveBufferSizePredictor(); + private volatile ReceiveBufferSizePredictor predictor; + private volatile ReceiveBufferSizePredictorFactory predictorFactory = DEFAULT_PREDICTOR_FACTORY; private volatile int writeSpinCount = 16; DefaultNioSocketChannelConfig(Socket socket) { @@ -143,6 +148,17 @@ class DefaultNioSocketChannelConfig extends DefaultSocketChannelConfig } public ReceiveBufferSizePredictor getReceiveBufferSizePredictor() { + ReceiveBufferSizePredictor predictor = this.predictor; + if (predictor == null) { + try { + this.predictor = predictor = getReceiveBufferSizePredictorFactory().getPredictor(); + } catch (Exception e) { + throw new ChannelException( + "Failed to create a new " + + ReceiveBufferSizePredictor.class.getSimpleName() + '.', + e); + } + } return predictor; } @@ -154,6 +170,17 @@ class DefaultNioSocketChannelConfig extends DefaultSocketChannelConfig this.predictor = predictor; } + public ReceiveBufferSizePredictorFactory getReceiveBufferSizePredictorFactory() { + return predictorFactory; + } + + public void setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory predictorFactory) { + if (predictorFactory == null) { + throw new NullPointerException("predictorFactory"); + } + this.predictorFactory = predictorFactory; + } + public boolean isReadWriteFair() { logger.warn( "Detected an access to a deprecated configuration parameter: " + diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramChannelConfig.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramChannelConfig.java index ba12e6a508..290513e2ca 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramChannelConfig.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramChannelConfig.java @@ -18,10 +18,8 @@ package org.jboss.netty.channel.socket.nio; import java.nio.ByteBuffer; import java.nio.channels.WritableByteChannel; -import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictor; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelConfig; -import org.jboss.netty.channel.ReceiveBufferSizePredictor; import org.jboss.netty.channel.socket.DatagramChannel; import org.jboss.netty.channel.socket.DatagramChannelConfig; @@ -44,8 +42,6 @@ import org.jboss.netty.channel.socket.DatagramChannelConfig; * * {@code "writeSpinCount"}{@link #setWriteSpinCount(int)} * - * {@code "receiveBufferSizePredictor"}{@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} - * * * * @author The Netty Project (netty-dev@lists.jboss.org) @@ -108,18 +104,4 @@ public interface NioDatagramChannelConfig extends DatagramChannelConfig { * if the specified value is {@code 0} or less than {@code 0} */ void setWriteSpinCount(int writeSpinCount); - - /** - * Returns the {@link ReceiveBufferSizePredictor} which predicts the - * number of readable bytes in the socket receive buffer. The default - * predictor is {@link AdaptiveReceiveBufferSizePredictor}. - */ - ReceiveBufferSizePredictor getReceiveBufferSizePredictor(); - - /** - * Sets the {@link ReceiveBufferSizePredictor} which predicts the - * number of readable bytes in the socket receive buffer. The default - * predictor is {@link AdaptiveReceiveBufferSizePredictor}. - */ - void setReceiveBufferSizePredictor(ReceiveBufferSizePredictor predictor); } diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioSocketChannelConfig.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioSocketChannelConfig.java index 824a0cd10e..07f715ae44 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioSocketChannelConfig.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioSocketChannelConfig.java @@ -19,9 +19,11 @@ import java.nio.ByteBuffer; import java.nio.channels.WritableByteChannel; import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictor; +import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictorFactory; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelConfig; import org.jboss.netty.channel.ReceiveBufferSizePredictor; +import org.jboss.netty.channel.ReceiveBufferSizePredictorFactory; import org.jboss.netty.channel.socket.SocketChannel; import org.jboss.netty.channel.socket.SocketChannelConfig; @@ -46,6 +48,8 @@ import org.jboss.netty.channel.socket.SocketChannelConfig; * * {@code "receiveBufferSizePredictor"}{@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} * + * {@code "receiveBufferSizePredictorFactory"}{@link #setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory)} + * * {@code "readWriteFair"}{@link #setReadWriteFair(boolean)} * * @@ -113,17 +117,37 @@ public interface NioSocketChannelConfig extends SocketChannelConfig { /** * Returns the {@link ReceiveBufferSizePredictor} which predicts the * number of readable bytes in the socket receive buffer. The default - * predictor is {@link AdaptiveReceiveBufferSizePredictor}. + * predictor is {@link AdaptiveReceiveBufferSizePredictor}(64, 1024, 65536). */ ReceiveBufferSizePredictor getReceiveBufferSizePredictor(); /** * Sets the {@link ReceiveBufferSizePredictor} which predicts the * number of readable bytes in the socket receive buffer. The default - * predictor is {@link AdaptiveReceiveBufferSizePredictor}. + * predictor is {@link AdaptiveReceiveBufferSizePredictor}(64, 1024, 65536). */ void setReceiveBufferSizePredictor(ReceiveBufferSizePredictor predictor); + /** + * Returns the {@link ReceiveBufferSizePredictorFactory} which creates a new + * {@link ReceiveBufferSizePredictor} when a new channel is created and + * no {@link ReceiveBufferSizePredictor} was set. If no predictor was set + * for the channel, {@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} + * will be called with the new predictor. The default factory is + * {@link AdaptiveReceiveBufferSizePredictorFactory}(64, 1024, 65536). + */ + ReceiveBufferSizePredictorFactory getReceiveBufferSizePredictorFactory(); + + /** + * Sets the {@link ReceiveBufferSizePredictor} which creates a new + * {@link ReceiveBufferSizePredictor} when a new channel is created and + * no {@link ReceiveBufferSizePredictor} was set. If no predictor was set + * for the channel, {@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} + * will be called with the new predictor. The default factory is + * {@link AdaptiveReceiveBufferSizePredictorFactory}(64, 1024, 65536). + */ + void setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory predictorFactory); + /** * @deprecated This property has been replaced by the * {@code writeBufferHighWaterMark} and {@code writeBufferLowWaterMark}. diff --git a/src/main/java/org/jboss/netty/channel/xnio/DefaultXnioChannelConfig.java b/src/main/java/org/jboss/netty/channel/xnio/DefaultXnioChannelConfig.java index d0c41832e0..083f740ce6 100644 --- a/src/main/java/org/jboss/netty/channel/xnio/DefaultXnioChannelConfig.java +++ b/src/main/java/org/jboss/netty/channel/xnio/DefaultXnioChannelConfig.java @@ -20,9 +20,11 @@ import java.util.Map.Entry; import org.jboss.netty.buffer.ChannelBufferFactory; import org.jboss.netty.buffer.HeapChannelBufferFactory; -import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictor; +import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictorFactory; +import org.jboss.netty.channel.ChannelException; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.ReceiveBufferSizePredictor; +import org.jboss.netty.channel.ReceiveBufferSizePredictorFactory; import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLoggerFactory; import org.jboss.netty.util.internal.ConversionUtil; @@ -41,12 +43,15 @@ final class DefaultXnioChannelConfig implements XnioChannelConfig { private static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultXnioChannelConfig.class); + private static final ReceiveBufferSizePredictorFactory DEFAULT_PREDICTOR_FACTORY = + new AdaptiveReceiveBufferSizePredictorFactory(); + private volatile ChannelBufferFactory bufferFactory = HeapChannelBufferFactory.getInstance(); private volatile ChannelPipelineFactory pipelineFactory; private volatile int writeBufferHighWaterMark = 64 * 1024; private volatile int writeBufferLowWaterMark = 32 * 1024; - private volatile ReceiveBufferSizePredictor predictor = - new AdaptiveReceiveBufferSizePredictor(); + private volatile ReceiveBufferSizePredictor predictor; + private volatile ReceiveBufferSizePredictorFactory predictorFactory = DEFAULT_PREDICTOR_FACTORY; private volatile int writeSpinCount = 16; DefaultXnioChannelConfig() { @@ -145,6 +150,17 @@ final class DefaultXnioChannelConfig implements XnioChannelConfig { } public ReceiveBufferSizePredictor getReceiveBufferSizePredictor() { + ReceiveBufferSizePredictor predictor = this.predictor; + if (predictor == null) { + try { + this.predictor = predictor = getReceiveBufferSizePredictorFactory().getPredictor(); + } catch (Exception e) { + throw new ChannelException( + "Failed to create a new " + + ReceiveBufferSizePredictor.class.getSimpleName() + '.', + e); + } + } return predictor; } @@ -156,6 +172,17 @@ final class DefaultXnioChannelConfig implements XnioChannelConfig { this.predictor = predictor; } + public ReceiveBufferSizePredictorFactory getReceiveBufferSizePredictorFactory() { + return predictorFactory; + } + + public void setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory predictorFactory) { + if (predictorFactory == null) { + throw new NullPointerException("predictorFactory"); + } + this.predictorFactory = predictorFactory; + } + public ChannelPipelineFactory getPipelineFactory() { return pipelineFactory; } diff --git a/src/main/java/org/jboss/netty/channel/xnio/XnioChannelConfig.java b/src/main/java/org/jboss/netty/channel/xnio/XnioChannelConfig.java index 91d2101392..1b5c16d9b1 100644 --- a/src/main/java/org/jboss/netty/channel/xnio/XnioChannelConfig.java +++ b/src/main/java/org/jboss/netty/channel/xnio/XnioChannelConfig.java @@ -19,8 +19,10 @@ import java.nio.ByteBuffer; import java.nio.channels.WritableByteChannel; import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictor; +import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictorFactory; import org.jboss.netty.channel.ChannelConfig; import org.jboss.netty.channel.ReceiveBufferSizePredictor; +import org.jboss.netty.channel.ReceiveBufferSizePredictorFactory; import org.jboss.netty.channel.socket.SocketChannelConfig; /** @@ -39,6 +41,8 @@ import org.jboss.netty.channel.socket.SocketChannelConfig; * {@code "writeSpinCount"}{@link #setWriteSpinCount(int)} * * {@code "receiveBufferSizePredictor"}{@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} + * + * {@code "receiveBufferSizePredictorFactory"}{@link #setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory)} * * * @@ -79,14 +83,34 @@ public interface XnioChannelConfig extends ChannelConfig { /** * Returns the {@link ReceiveBufferSizePredictor} which predicts the * number of readable bytes in the socket receive buffer. The default - * predictor is {@link AdaptiveReceiveBufferSizePredictor}. + * predictor is {@link AdaptiveReceiveBufferSizePredictor}(64, 1024, 65536). */ ReceiveBufferSizePredictor getReceiveBufferSizePredictor(); /** * Sets the {@link ReceiveBufferSizePredictor} which predicts the * number of readable bytes in the socket receive buffer. The default - * predictor is {@link AdaptiveReceiveBufferSizePredictor}. + * predictor is {@link AdaptiveReceiveBufferSizePredictor}(64, 1024, 65536). */ void setReceiveBufferSizePredictor(ReceiveBufferSizePredictor predictor); + + /** + * Returns the {@link ReceiveBufferSizePredictorFactory} which creates a new + * {@link ReceiveBufferSizePredictor} when a new channel is created and + * no {@link ReceiveBufferSizePredictor} was set. If no predictor was set + * for the channel, {@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} + * will be called with the new predictor. The default factory is + * {@link AdaptiveReceiveBufferSizePredictorFactory}(64, 1024, 65536). + */ + ReceiveBufferSizePredictorFactory getReceiveBufferSizePredictorFactory(); + + /** + * Sets the {@link ReceiveBufferSizePredictor} which creates a new + * {@link ReceiveBufferSizePredictor} when a new channel is created and + * no {@link ReceiveBufferSizePredictor} was set. If no predictor was set + * for the channel, {@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} + * will be called with the new predictor. The default factory is + * {@link AdaptiveReceiveBufferSizePredictorFactory}(64, 1024, 65536). + */ + void setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory predictorFactory); }