context)
parser.setMaxFrameLength(client.getMaxFrameLength());
parser.setMaxSettingsKeys(client.getMaxSettingsKeys());
- RetainableByteBufferPool retainableByteBufferPool = RetainableByteBufferPool.findOrAdapt(client, byteBufferPool);
+ RetainableByteBufferPool retainableByteBufferPool = byteBufferPool.asRetainableByteBufferPool();
HTTP2ClientConnection connection = new HTTP2ClientConnection(client, retainableByteBufferPool, executor, endPoint,
parser, session, client.getInputBufferSize(), promise, listener);
diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java
index ae180edf9e12..60937d5bdc65 100644
--- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java
+++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java
@@ -280,7 +280,7 @@ public Connection newConnection(Connector connector, EndPoint endPoint)
parser.setMaxFrameLength(getMaxFrameLength());
parser.setMaxSettingsKeys(getMaxSettingsKeys());
- RetainableByteBufferPool retainableByteBufferPool = RetainableByteBufferPool.findOrAdapt(connector, connector.getByteBufferPool());
+ RetainableByteBufferPool retainableByteBufferPool = connector.getByteBufferPool().asRetainableByteBufferPool();
HTTP2Connection connection = new HTTP2ServerConnection(retainableByteBufferPool, connector.getExecutor(),
endPoint, httpConfiguration, parser, session, getInputBufferSize(), listener);
diff --git a/jetty-http3/http3-common/src/main/java/org/eclipse/jetty/http3/internal/HTTP3StreamConnection.java b/jetty-http3/http3-common/src/main/java/org/eclipse/jetty/http3/internal/HTTP3StreamConnection.java
index d7d3de5e3df7..4cbe3e530792 100644
--- a/jetty-http3/http3-common/src/main/java/org/eclipse/jetty/http3/internal/HTTP3StreamConnection.java
+++ b/jetty-http3/http3-common/src/main/java/org/eclipse/jetty/http3/internal/HTTP3StreamConnection.java
@@ -57,7 +57,7 @@ public abstract class HTTP3StreamConnection extends AbstractConnection
public HTTP3StreamConnection(QuicStreamEndPoint endPoint, Executor executor, ByteBufferPool byteBufferPool, MessageParser parser)
{
super(endPoint, executor);
- this.buffers = RetainableByteBufferPool.findOrAdapt(null, byteBufferPool);
+ this.buffers = byteBufferPool.asRetainableByteBufferPool();
this.parser = parser;
parser.init(MessageListener::new);
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
index f73229aa5131..81549ec0981c 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
@@ -96,7 +96,7 @@ public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity, int max
*/
public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity, int maxBucketSize, long maxHeapMemory, long maxDirectMemory)
{
- this(minCapacity, factor, maxCapacity, maxBucketSize, maxHeapMemory, maxDirectMemory, 0, 0);
+ this(minCapacity, factor, maxCapacity, maxBucketSize, maxHeapMemory, maxDirectMemory, -1, -1);
}
/**
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferPool.java
index 285548458795..e6433a843d19 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferPool.java
@@ -75,12 +75,9 @@ default ByteBuffer newByteBuffer(int capacity, boolean direct)
/**
* Get this pool as a {@link RetainableByteBufferPool}, which supports reference counting of the
* buffers and possibly a more efficient lookup mechanism based on the {@link org.eclipse.jetty.util.Pool} class.
- * @return This pool wrapped as a RetainableByteBufferPool.
+ * @return This pool as a RetainableByteBufferPool. The same instance is always returned by multiple calls to this method.
*/
- default RetainableByteBufferPool asRetainableByteBufferPool()
- {
- return RetainableByteBufferPool.from(this);
- }
+ RetainableByteBufferPool asRetainableByteBufferPool();
class Lease
{
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java
index d01e10cc8091..d78710959112 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java
@@ -63,7 +63,23 @@ public LogarithmicArrayByteBufferPool(int minCapacity, int maxCapacity, int maxQ
*/
public LogarithmicArrayByteBufferPool(int minCapacity, int maxCapacity, int maxQueueLength, long maxHeapMemory, long maxDirectMemory)
{
- super(minCapacity, 1, maxCapacity, maxQueueLength, maxHeapMemory, maxDirectMemory);
+ this(minCapacity, maxCapacity, maxQueueLength, maxHeapMemory, maxDirectMemory, -1, -1);
+ }
+
+ /**
+ * Creates a new ByteBufferPool with the given configuration.
+ *
+ * @param minCapacity the minimum ByteBuffer capacity
+ * @param maxCapacity the maximum ByteBuffer capacity
+ * @param maxQueueLength the maximum ByteBuffer queue length
+ * @param maxHeapMemory the max heap memory in bytes
+ * @param maxDirectMemory the max direct memory in bytes
+ * @param retainedHeapMemory the max heap memory in bytes, -1 for no retained memory or 0 to use default heuristic
+ * @param retainedDirectMemory the max direct memory in bytes, -1 for no retained memory or 0 to use default heuristic
+ */
+ public LogarithmicArrayByteBufferPool(int minCapacity, int maxCapacity, int maxQueueLength, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
+ {
+ super(minCapacity, 1, maxCapacity, maxQueueLength, maxHeapMemory, maxDirectMemory, retainedHeapMemory, retainedDirectMemory);
}
@Override
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/NullByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/NullByteBufferPool.java
index 217e658aae2b..88ab24651f68 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/NullByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/NullByteBufferPool.java
@@ -19,6 +19,8 @@
public class NullByteBufferPool implements ByteBufferPool
{
+ private RetainableByteBufferPool _retainableByteBufferPool = RetainableByteBufferPool.from(this);
+
@Override
public ByteBuffer acquire(int size, boolean direct)
{
@@ -33,4 +35,10 @@ public void release(ByteBuffer buffer)
{
BufferUtil.clear(buffer);
}
+
+ @Override
+ public RetainableByteBufferPool asRetainableByteBufferPool()
+ {
+ return _retainableByteBufferPool;
+ }
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/RetainableByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/RetainableByteBufferPool.java
index 91f921e750eb..0831bb636c84 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/RetainableByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/RetainableByteBufferPool.java
@@ -15,8 +15,6 @@
import java.nio.ByteBuffer;
-import org.eclipse.jetty.util.component.Container;
-
/**
* A {@link RetainableByteBuffer} pool.
* Acquired buffers must be released by calling {@link RetainableByteBuffer#release()} otherwise the memory they hold will
@@ -32,19 +30,6 @@ public interface RetainableByteBufferPool
*/
RetainableByteBuffer acquire(int size, boolean direct);
- /**
- * Finds a {@link RetainableByteBufferPool} implementation in the given container, or wrap the given
- * {@link ByteBufferPool} with an adapter.
- * @param container the container to search for an existing memory pool.
- * @param byteBufferPool Use {@link ByteBufferPool#asRetainableByteBufferPool()} to convert if no memory pool was found in the container.
- * @return the {@link RetainableByteBufferPool} found or the converted one.
- */
- static RetainableByteBufferPool findOrAdapt(Container container, ByteBufferPool byteBufferPool)
- {
- RetainableByteBufferPool retainableByteBufferPool = container == null ? null : container.getBean(RetainableByteBufferPool.class);
- return retainableByteBufferPool == null ? byteBufferPool.asRetainableByteBufferPool() : retainableByteBufferPool;
- }
-
static RetainableByteBufferPool from(ByteBufferPool byteBufferPool)
{
return new RetainableByteBufferPool()
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java
index 62214a1f866a..a0767bd0ab55 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java
@@ -173,7 +173,7 @@ public SslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint
public SslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine sslEngine,
boolean useDirectBuffersForEncryption, boolean useDirectBuffersForDecryption)
{
- this(RetainableByteBufferPool.findOrAdapt(null, byteBufferPool), byteBufferPool, executor, endPoint, sslEngine, useDirectBuffersForEncryption, useDirectBuffersForDecryption);
+ this(byteBufferPool.asRetainableByteBufferPool(), byteBufferPool, executor, endPoint, sslEngine, useDirectBuffersForEncryption, useDirectBuffersForDecryption);
}
public SslConnection(RetainableByteBufferPool retainableByteBufferPool, ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine sslEngine,
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
index 7cb8437c591f..d69d9c9d39ed 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -187,7 +187,9 @@ public AbstractConnector(
addBean(_scheduler);
if (pool == null)
pool = _server.getBean(ByteBufferPool.class);
- _byteBufferPool = pool != null ? pool : new ArrayByteBufferPool();
+
+ // TODO improve this
+ _byteBufferPool = pool != null ? pool : new ArrayByteBufferPool(-1, -1, -1, -1, -1, -1, 0, 0);
addBean(_byteBufferPool, pool == null);
addEventListener(new Container.Listener()
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java
index aaf11cf501c8..23bf34db3d1c 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java
@@ -97,7 +97,7 @@ public HttpConnection(HttpConfiguration config, Connector connector, EndPoint en
_config = config;
_connector = connector;
_bufferPool = _connector.getByteBufferPool();
- _retainableByteBufferPool = RetainableByteBufferPool.findOrAdapt(connector, _bufferPool);
+ _retainableByteBufferPool = _bufferPool.asRetainableByteBufferPool();
_generator = newHttpGenerator();
_channel = newHttpChannel();
_input = _channel.getRequest().getHttpInput();
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java
index 0d44be120c35..5b351cbd805d 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java
@@ -168,7 +168,7 @@ public Connection newConnection(Connector connector, EndPoint endPoint)
protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine)
{
ByteBufferPool byteBufferPool = connector.getByteBufferPool();
- RetainableByteBufferPool retainableByteBufferPool = RetainableByteBufferPool.findOrAdapt(connector, byteBufferPool);
+ RetainableByteBufferPool retainableByteBufferPool = byteBufferPool.asRetainableByteBufferPool();
return new SslConnection(retainableByteBufferPool, byteBufferPool, connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption());
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpOutputTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpOutputTest.java
index 340d53158f30..ce8e8c0beec2 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpOutputTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpOutputTest.java
@@ -31,7 +31,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.NullByteBufferPool;
import org.eclipse.jetty.server.HttpOutput.Interceptor;
import org.eclipse.jetty.server.LocalConnector.LocalEndPoint;
import org.eclipse.jetty.server.handler.AbstractHandler;
@@ -69,19 +69,7 @@ public void init() throws Exception
{
_server = new Server();
- _server.addBean(new ByteBufferPool()
- {
- @Override
- public ByteBuffer acquire(int size, boolean direct)
- {
- return direct ? BufferUtil.allocateDirect(size) : BufferUtil.allocate(size);
- }
-
- @Override
- public void release(ByteBuffer buffer)
- {
- }
- });
+ _server.addBean(new NullByteBufferPool());
HttpConnectionFactory http = new HttpConnectionFactory();
http.getHttpConfiguration().setRequestHeaderSize(1024);
diff --git a/jetty-websocket/websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/CoreClientUpgradeRequest.java b/jetty-websocket/websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/CoreClientUpgradeRequest.java
index 2008c5b91f83..3255bec5c074 100644
--- a/jetty-websocket/websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/CoreClientUpgradeRequest.java
+++ b/jetty-websocket/websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/CoreClientUpgradeRequest.java
@@ -440,7 +440,7 @@ else if (values.length == 1)
HttpClient httpClient = wsClient.getHttpClient();
ByteBufferPool bufferPool = wsClient.getWebSocketComponents().getBufferPool();
- RetainableByteBufferPool retainableByteBufferPool = RetainableByteBufferPool.findOrAdapt(wsClient.getWebSocketComponents(), bufferPool);
+ RetainableByteBufferPool retainableByteBufferPool = bufferPool.asRetainableByteBufferPool();
WebSocketConnection wsConnection = new WebSocketConnection(endPoint, httpClient.getExecutor(), httpClient.getScheduler(), bufferPool, retainableByteBufferPool, coreSession);
wsClient.getEventListeners().forEach(wsConnection::addEventListener);
coreSession.setWebSocketConnection(wsConnection);
diff --git a/jetty-websocket/websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java b/jetty-websocket/websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java
index bca2538a1c3a..60af7246031a 100644
--- a/jetty-websocket/websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java
+++ b/jetty-websocket/websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java
@@ -97,7 +97,7 @@ protected WebSocketConnection createWebSocketConnection(Request baseRequest, Web
HttpChannel httpChannel = baseRequest.getHttpChannel();
Connector connector = httpChannel.getConnector();
ByteBufferPool byteBufferPool = connector.getByteBufferPool();
- RetainableByteBufferPool retainableByteBufferPool = RetainableByteBufferPool.findOrAdapt(connector, byteBufferPool);
+ RetainableByteBufferPool retainableByteBufferPool = byteBufferPool.asRetainableByteBufferPool();
return newWebSocketConnection(httpChannel.getEndPoint(), connector.getExecutor(), connector.getScheduler(), byteBufferPool, retainableByteBufferPool, coreSession);
}
diff --git a/jetty-websocket/websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java b/jetty-websocket/websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java
index 83c79d5bd9e3..4aebf3fa3461 100644
--- a/jetty-websocket/websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java
+++ b/jetty-websocket/websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java
@@ -81,7 +81,7 @@ protected WebSocketConnection createWebSocketConnection(Request baseRequest, Web
Connector connector = httpChannel.getConnector();
EndPoint endPoint = httpChannel.getTunnellingEndPoint();
ByteBufferPool byteBufferPool = connector.getByteBufferPool();
- RetainableByteBufferPool retainableByteBufferPool = RetainableByteBufferPool.findOrAdapt(connector, byteBufferPool);
+ RetainableByteBufferPool retainableByteBufferPool = byteBufferPool.asRetainableByteBufferPool();
return newWebSocketConnection(endPoint, connector.getExecutor(), connector.getScheduler(), byteBufferPool, retainableByteBufferPool, coreSession);
}
From 417baf26449fcdbe1a7f88b9eb4848ffbd840fe3 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Tue, 28 Jun 2022 10:29:02 +1000
Subject: [PATCH 09/24] cleanup defaults
Signed-off-by: Greg Wilkins
---
.../jetty/io/AbstractByteBufferPool.java | 34 +++++++++++------
.../eclipse/jetty/io/ArrayByteBufferPool.java | 6 +--
.../io/LogarithmicArrayByteBufferPool.java | 6 +--
.../jetty/io/MappedByteBufferPool.java | 38 +++++++++++++++++--
.../jetty/io/MappedByteBufferPoolTest.java | 2 +-
.../main/config/modules/bytebufferpool.mod | 1 +
.../jetty/server/AbstractConnector.java | 25 ++++++++++--
7 files changed, 86 insertions(+), 26 deletions(-)
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java
index 1f6987c8c5d9..c3efeb337dd3 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java
@@ -50,23 +50,35 @@ abstract class AbstractByteBufferPool implements ByteBufferPool
* @param maxBucketSize the maximum ByteBuffer queue length
* @param maxHeapMemory the max heap memory in bytes, -1 for unlimited memory or 0 to use default heuristic
* @param maxDirectMemory the max direct memory in bytes, -1 for unlimited memory or 0 to use default heuristic
- * @param retainedHeapMemory the max heap memory in bytes, -1 for no retained memory or 0 to use default heuristic
- * @param retainedDirectMemory the max direct memory in bytes, -1 for no retained memory or 0 to use default heuristic
+ * @param retainedHeapMemory the max heap memory in bytes, -2 for no retained memory, -1 for unlimited retained memory or 0 to use default heuristic
+ * @param retainedDirectMemory the max direct memory in bytes, -2 for no retained memory, -1 for unlimited retained memory or 0 to use default heuristic
*/
protected AbstractByteBufferPool(int factor, int maxCapacity, int maxBucketSize, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
{
_factor = factor <= 0 ? 1024 : factor;
_maxCapacity = maxCapacity > 0 ? maxCapacity : 64 * _factor;
_maxBucketSize = maxBucketSize;
- _maxHeapMemory = (maxHeapMemory != 0) ? maxHeapMemory : Runtime.getRuntime().maxMemory() / 4;
- _maxDirectMemory = (maxDirectMemory != 0) ? maxDirectMemory : Runtime.getRuntime().maxMemory() / 4;
-
- if (retainedHeapMemory < 0 && retainedDirectMemory < 0)
- _retainableByteBufferPool = RetainableByteBufferPool.from(this);
- else
- _retainableByteBufferPool = newRetainableByteBufferPool(factor, maxCapacity, maxBucketSize,
- (retainedHeapMemory != 0) ? retainedHeapMemory : Runtime.getRuntime().maxMemory() / 4,
- (retainedDirectMemory != 0) ? retainedDirectMemory : Runtime.getRuntime().maxMemory() / 4);
+ _maxHeapMemory = memorySize(maxHeapMemory);
+ _maxDirectMemory = memorySize(maxDirectMemory);
+ _retainableByteBufferPool = (retainedHeapMemory == -2 && retainedDirectMemory == -2)
+ ? RetainableByteBufferPool.from(this)
+ : newRetainableByteBufferPool(factor, maxCapacity, maxBucketSize, retainedSize(retainedHeapMemory), retainedSize(retainedDirectMemory));
+ }
+
+ private static long retainedSize(long size)
+ {
+ if (size == -2)
+ return 0;
+ return memorySize(size);
+ }
+
+ private static long memorySize(long size)
+ {
+ if (size < 0)
+ return -1;
+ if (size == 0)
+ return Runtime.getRuntime().maxMemory() / 4;
+ return size;
}
protected RetainableByteBufferPool newRetainableByteBufferPool(int factor, int maxCapacity, int maxBucketSize, long retainedHeapMemory, long retainedDirectMemory)
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
index 81549ec0981c..1b52c7be2607 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
@@ -96,7 +96,7 @@ public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity, int max
*/
public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity, int maxBucketSize, long maxHeapMemory, long maxDirectMemory)
{
- this(minCapacity, factor, maxCapacity, maxBucketSize, maxHeapMemory, maxDirectMemory, -1, -1);
+ this(minCapacity, factor, maxCapacity, maxBucketSize, maxHeapMemory, maxDirectMemory, maxHeapMemory, maxDirectMemory);
}
/**
@@ -108,8 +108,8 @@ public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity, int max
* @param maxBucketSize the maximum ByteBuffer queue length in a {@link Bucket}
* @param maxHeapMemory the max heap memory in bytes, -1 for unlimited memory or 0 to use default heuristic
* @param maxDirectMemory the max direct memory in bytes, -1 for unlimited memory or 0 to use default heuristic
- * @param retainedHeapMemory the max heap memory in bytes, -1 for no retained memory or 0 to use default heuristic
- * @param retainedDirectMemory the max direct memory in bytes, -1 for no retained memory or 0 to use default heuristic
+ * @param retainedHeapMemory the max heap memory in bytes, -2 for no retained memory, -1 for unlimited retained memory or 0 to use default heuristic
+ * @param retainedDirectMemory the max direct memory in bytes, -2 for no retained memory, -1 for unlimited retained memory or 0 to use default heuristic
*/
public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity, int maxBucketSize, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
{
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java
index d78710959112..db586a0ae4b0 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java
@@ -63,7 +63,7 @@ public LogarithmicArrayByteBufferPool(int minCapacity, int maxCapacity, int maxQ
*/
public LogarithmicArrayByteBufferPool(int minCapacity, int maxCapacity, int maxQueueLength, long maxHeapMemory, long maxDirectMemory)
{
- this(minCapacity, maxCapacity, maxQueueLength, maxHeapMemory, maxDirectMemory, -1, -1);
+ this(minCapacity, maxCapacity, maxQueueLength, maxHeapMemory, maxDirectMemory, maxHeapMemory, maxDirectMemory);
}
/**
@@ -74,8 +74,8 @@ public LogarithmicArrayByteBufferPool(int minCapacity, int maxCapacity, int maxQ
* @param maxQueueLength the maximum ByteBuffer queue length
* @param maxHeapMemory the max heap memory in bytes
* @param maxDirectMemory the max direct memory in bytes
- * @param retainedHeapMemory the max heap memory in bytes, -1 for no retained memory or 0 to use default heuristic
- * @param retainedDirectMemory the max direct memory in bytes, -1 for no retained memory or 0 to use default heuristic
+ * @param retainedHeapMemory the max heap memory in bytes, -1 for unlimited retained memory or 0 to use default heuristic
+ * @param retainedDirectMemory the max direct memory in bytes, -1 for unlimited retained memory or 0 to use default heuristic
*/
public LogarithmicArrayByteBufferPool(int minCapacity, int maxCapacity, int maxQueueLength, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
{
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java
index 59c86a1ac8c5..4ac8f482e568 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java
@@ -83,11 +83,39 @@ public MappedByteBufferPool(int factor, int maxQueueLength)
* @param maxQueueLength the maximum ByteBuffer queue length
* @param newBucket the function that creates a Bucket
*/
- public MappedByteBufferPool(int factor, int maxQueueLength, Function newBucket)
+ private MappedByteBufferPool(int factor, int maxQueueLength, Function newBucket)
{
- this(factor, maxQueueLength, newBucket, 0, 0);
+ this(factor, maxQueueLength, newBucket, -1, -1, -1, -1);
}
+ /**
+ * Creates a new MappedByteBufferPool with the given configuration.
+ *
+ * @param factor the capacity factor
+ * @param maxQueueLength the maximum ByteBuffer queue length
+ * @param maxHeapMemory the max heap memory in bytes, -1 for unlimited memory or 0 to use default heuristic.
+ * @param maxDirectMemory the max direct memory in bytes, -1 for unlimited memory or 0 to use default heuristic.
+ */
+ public MappedByteBufferPool(int factor, int maxQueueLength, long maxHeapMemory, long maxDirectMemory)
+ {
+ this(factor, maxQueueLength, null, maxHeapMemory, maxDirectMemory, maxHeapMemory, maxDirectMemory);
+ }
+
+ /**
+ * Creates a new MappedByteBufferPool with the given configuration.
+ *
+ * @param factor the capacity factor
+ * @param maxQueueLength the maximum ByteBuffer queue length
+ * @param maxHeapMemory the max heap memory in bytes, -1 for unlimited memory or 0 to use default heuristic.
+ * @param maxDirectMemory the max direct memory in bytes, -1 for unlimited memory or 0 to use default heuristic.
+ * @param retainedHeapMemory the max heap memory in bytes, -2 for no retained memory, -1 for unlimited retained memory or 0 to use default heuristic
+ * @param retainedDirectMemory the max direct memory in bytes, -2 for no retained memory, -1 for unlimited retained memory or 0 to use default heuristic
+ */
+ public MappedByteBufferPool(int factor, int maxQueueLength, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
+ {
+ this(factor, maxQueueLength, null, maxHeapMemory, maxDirectMemory, retainedHeapMemory, retainedDirectMemory);
+ }
+
/**
* Creates a new MappedByteBufferPool with the given configuration.
*
@@ -96,10 +124,12 @@ public MappedByteBufferPool(int factor, int maxQueueLength, Function newBucket, long maxHeapMemory, long maxDirectMemory)
+ private MappedByteBufferPool(int factor, int maxQueueLength, Function newBucket, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
{
- super(factor, 0, maxQueueLength, maxHeapMemory, maxDirectMemory, -1, -1);
+ super(factor, 0, maxQueueLength, maxHeapMemory, maxDirectMemory, retainedHeapMemory, retainedDirectMemory);
_newBucket = newBucket;
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/MappedByteBufferPoolTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/MappedByteBufferPoolTest.java
index 1b4f1ae7d3f7..8fec072dc3d3 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/MappedByteBufferPoolTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/MappedByteBufferPoolTest.java
@@ -138,7 +138,7 @@ public void testMaxMemory()
{
int factor = 1024;
int maxMemory = 11 * factor;
- MappedByteBufferPool bufferPool = new MappedByteBufferPool(factor, -1, null, -1, maxMemory);
+ MappedByteBufferPool bufferPool = new MappedByteBufferPool(factor, -1, -1, maxMemory);
ConcurrentMap buckets = bufferPool.bucketsFor(true);
// Create the buckets - the oldest is the larger.
diff --git a/jetty-server/src/main/config/modules/bytebufferpool.mod b/jetty-server/src/main/config/modules/bytebufferpool.mod
index 1992935035da..f229fb7eeb36 100644
--- a/jetty-server/src/main/config/modules/bytebufferpool.mod
+++ b/jetty-server/src/main/config/modules/bytebufferpool.mod
@@ -1,5 +1,6 @@
[description]
Configures the ByteBufferPool used by ServerConnectors.
+Use module "bytebufferpool-logarithmic" for a more space efficient pool.
[tags]
bytebufferpool
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
index d69d9c9d39ed..48abdeef43fc 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -34,6 +34,7 @@
import org.eclipse.jetty.io.ArrayByteBufferPool;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.LogarithmicArrayByteBufferPool;
import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.StringUtil;
@@ -185,11 +186,27 @@ public AbstractConnector(
scheduler = _server.getBean(Scheduler.class);
_scheduler = scheduler != null ? scheduler : new ScheduledExecutorScheduler(String.format("Connector-Scheduler-%x", hashCode()), false);
addBean(_scheduler);
- if (pool == null)
- pool = _server.getBean(ByteBufferPool.class);
- // TODO improve this
- _byteBufferPool = pool != null ? pool : new ArrayByteBufferPool(-1, -1, -1, -1, -1, -1, 0, 0);
+ synchronized (server)
+ {
+ if (pool == null)
+ {
+ // Look for (and cache) a common pool on the server
+ pool = server.getBean(ByteBufferPool.class);
+ if (pool == null)
+ {
+ pool = new LogarithmicArrayByteBufferPool();
+ server.addBean(pool, true);
+ }
+ addBean(pool, false);
+ }
+ else
+ {
+ addBean(pool, true);
+ }
+ }
+
+ _byteBufferPool = pool;
addBean(_byteBufferPool, pool == null);
addEventListener(new Container.Listener()
From 9d388727b9a277455ac4ceca05839a6a1725d880 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Tue, 28 Jun 2022 10:31:42 +1000
Subject: [PATCH 10/24] Combined ByteBufferPool
Suspected bug in log pool?
Signed-off-by: Greg Wilkins
---
.../main/java/org/eclipse/jetty/server/AbstractConnector.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
index 48abdeef43fc..e538ed78fe29 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -34,7 +34,6 @@
import org.eclipse.jetty.io.ArrayByteBufferPool;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.LogarithmicArrayByteBufferPool;
import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.StringUtil;
@@ -195,7 +194,7 @@ public AbstractConnector(
pool = server.getBean(ByteBufferPool.class);
if (pool == null)
{
- pool = new LogarithmicArrayByteBufferPool();
+ pool = new ArrayByteBufferPool();
server.addBean(pool, true);
}
addBean(pool, false);
From 58461e0a38d51e7b1cef905e9754cde6a87d2fd8 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Tue, 28 Jun 2022 11:26:02 +1000
Subject: [PATCH 11/24] Combined ByteBufferPool
Increased default factor to reduce buckets.
Test LogarithmicArrayByteBufferPool
Signed-off-by: Greg Wilkins
---
.../jetty/io/AbstractByteBufferPool.java | 2 +-
.../io/ArrayRetainableByteBufferPool.java | 2 +-
.../io/LogarithmicArrayByteBufferPool.java | 38 ++++++++++++++++++-
.../io/ArrayRetainableByteBufferPoolTest.java | 31 +++++++++++++++
.../java/org/eclipse/jetty/util/Pool.java | 2 +-
5 files changed, 71 insertions(+), 4 deletions(-)
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java
index c3efeb337dd3..fbaa9a0d4690 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java
@@ -55,7 +55,7 @@ abstract class AbstractByteBufferPool implements ByteBufferPool
*/
protected AbstractByteBufferPool(int factor, int maxCapacity, int maxBucketSize, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
{
- _factor = factor <= 0 ? 1024 : factor;
+ _factor = factor <= 0 ? 4096 : factor;
_maxCapacity = maxCapacity > 0 ? maxCapacity : 64 * _factor;
_maxBucketSize = maxBucketSize;
_maxHeapMemory = memorySize(maxHeapMemory);
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPool.java
index e66e42e942e0..90411f155da5 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPool.java
@@ -113,7 +113,7 @@ protected ArrayRetainableByteBufferPool(int minCapacity, int factor, int maxCapa
if (maxCapacity <= 0)
maxCapacity = 64 * 1024;
- int f = factor <= 0 ? 1024 : factor;
+ int f = factor <= 0 ? 4096 : factor;
if ((maxCapacity % f) != 0 || f >= maxCapacity)
throw new IllegalArgumentException(String.format("The capacity factor(%d) must be a divisor of maxCapacity(%d)", f, maxCapacity));
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java
index db586a0ae4b0..9435289cc79f 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/LogarithmicArrayByteBufferPool.java
@@ -79,7 +79,13 @@ public LogarithmicArrayByteBufferPool(int minCapacity, int maxCapacity, int maxQ
*/
public LogarithmicArrayByteBufferPool(int minCapacity, int maxCapacity, int maxQueueLength, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
{
- super(minCapacity, 1, maxCapacity, maxQueueLength, maxHeapMemory, maxDirectMemory, retainedHeapMemory, retainedDirectMemory);
+ super(minCapacity, -1, maxCapacity, maxQueueLength, maxHeapMemory, maxDirectMemory, retainedHeapMemory, retainedDirectMemory);
+ }
+
+ @Override
+ protected RetainableByteBufferPool newRetainableByteBufferPool(int factor, int maxCapacity, int maxBucketSize, long retainedHeapMemory, long retainedDirectMemory)
+ {
+ return new LogarithmicRetainablePool(0, maxCapacity, maxBucketSize, retainedHeapMemory, retainedDirectMemory);
}
@Override
@@ -120,4 +126,34 @@ protected void releaseMemory(boolean direct)
bucket.resetUpdateTime();
}
}
+
+ /**
+ * A variant of the {@link ArrayRetainableByteBufferPool} that
+ * uses buckets of buffers that increase in size by a power of
+ * 2 (eg 1k, 2k, 4k, 8k, etc.).
+ */
+ public static class LogarithmicRetainablePool extends ArrayRetainableByteBufferPool
+ {
+ public LogarithmicRetainablePool()
+ {
+ this(0, -1, Integer.MAX_VALUE);
+ }
+
+ public LogarithmicRetainablePool(int minCapacity, int maxCapacity, int maxBucketSize)
+ {
+ this(minCapacity, maxCapacity, maxBucketSize, -1L, -1L);
+ }
+
+ public LogarithmicRetainablePool(int minCapacity, int maxCapacity, int maxBucketSize, long maxHeapMemory, long maxDirectMemory)
+ {
+ super(minCapacity,
+ -1,
+ maxCapacity,
+ maxBucketSize,
+ maxHeapMemory,
+ maxDirectMemory,
+ c -> 32 - Integer.numberOfLeadingZeros(c - 1),
+ i -> 1 << i);
+ }
+ }
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
index 816352a60d3b..957d9f725246 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
@@ -14,6 +14,7 @@
package org.eclipse.jetty.io;
import java.io.IOException;
+import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
@@ -26,7 +27,9 @@
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.lessThan;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
+import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.sameInstance;
import static org.hamcrest.core.Is.is;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -391,4 +394,32 @@ public void testEndiannessResetOnRelease()
assertThat(buffer.release(), is(true));
assertThat(buffer.getBuffer().order(), Matchers.is(ByteOrder.BIG_ENDIAN));
}
+
+ @Test
+ void testLogarithmic()
+ {
+ LogarithmicArrayByteBufferPool pool = new LogarithmicArrayByteBufferPool();
+ ByteBuffer buffer5 = pool.acquire(5, false);
+ pool.release(buffer5);
+ ByteBuffer buffer6 = pool.acquire(6, false);
+ assertThat(buffer6, sameInstance(buffer5));
+ pool.release(buffer6);
+ ByteBuffer buffer9 = pool.acquire(9, false);
+ assertThat(buffer9, not(sameInstance(buffer5)));
+ pool.release(buffer9);
+
+ RetainableByteBufferPool retainablePool = pool.asRetainableByteBufferPool();
+
+ RetainableByteBuffer retain5 = retainablePool.acquire(5, false);
+ retain5.release();
+ RetainableByteBuffer retain6 = retainablePool.acquire(6, false);
+ System.err.println(pool.dump());
+ assertThat(retain6, sameInstance(retain5));
+ retain6.release();
+ RetainableByteBuffer retain9 = retainablePool.acquire(9, false);
+ assertThat(retain9, not(sameInstance(retain5)));
+ retain9.release();
+
+ System.err.println(pool.dump());
+ }
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/Pool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/Pool.java
index 8e12c4f74b25..fa86d040e16f 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/Pool.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/Pool.java
@@ -339,7 +339,7 @@ public Entry reserve()
return null;
// If we have no space
- if (entries.size() >= maxEntries)
+ if (maxEntries > 0 && entries.size() >= maxEntries)
return null;
Entry entry = newEntry();
From 7cdd0b7af938f236c0aa4823e2f98bb92a88757d Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Tue, 28 Jun 2022 13:42:46 +1000
Subject: [PATCH 12/24] Combined ByteBufferPool
Further fixes to defaults and tests
Signed-off-by: Greg Wilkins
---
.../eclipse/jetty/io/AbstractByteBufferPool.java | 10 ++++++----
.../eclipse/jetty/io/ArrayByteBufferPool.java | 16 ++++++++++++++--
.../jetty/io/ArrayRetainableByteBufferPool.java | 14 +++++++-------
.../io/ArrayRetainableByteBufferPoolTest.java | 10 +++++-----
4 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java
index fbaa9a0d4690..544825e0adf0 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java
@@ -34,6 +34,8 @@
@ManagedObject
abstract class AbstractByteBufferPool implements ByteBufferPool
{
+ public static final Integer DEFAULT_FACTOR = 4096;
+ public static final Integer DEFAULT_MAX_CAPACITY_BY_FACTOR = 16;
private final int _factor;
private final int _maxCapacity;
private final int _maxBucketSize;
@@ -55,8 +57,8 @@ abstract class AbstractByteBufferPool implements ByteBufferPool
*/
protected AbstractByteBufferPool(int factor, int maxCapacity, int maxBucketSize, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
{
- _factor = factor <= 0 ? 4096 : factor;
- _maxCapacity = maxCapacity > 0 ? maxCapacity : 64 * _factor;
+ _factor = factor <= 0 ? DEFAULT_FACTOR : factor;
+ _maxCapacity = maxCapacity > 0 ? maxCapacity : DEFAULT_MAX_CAPACITY_BY_FACTOR * _factor;
_maxBucketSize = maxBucketSize;
_maxHeapMemory = memorySize(maxHeapMemory);
_maxDirectMemory = memorySize(maxDirectMemory);
@@ -65,14 +67,14 @@ protected AbstractByteBufferPool(int factor, int maxCapacity, int maxBucketSize,
: newRetainableByteBufferPool(factor, maxCapacity, maxBucketSize, retainedSize(retainedHeapMemory), retainedSize(retainedDirectMemory));
}
- private static long retainedSize(long size)
+ static long retainedSize(long size)
{
if (size == -2)
return 0;
return memorySize(size);
}
- private static long memorySize(long size)
+ static long memorySize(long size)
{
if (size < 0)
return -1;
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
index 1b52c7be2607..8ff571d550bf 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
@@ -57,6 +57,18 @@ public ArrayByteBufferPool()
this(-1, -1, -1);
}
+ /**
+ * Creates a new ArrayByteBufferPool with a default configuration.
+ * Both {@code maxHeapMemory} and {@code maxDirectMemory} default to 0 to use default heuristic.
+ * @param retainable True if {@link #asRetainableByteBufferPool()} return a real implementation.
+ */
+ public ArrayByteBufferPool(boolean retainable)
+ {
+ this(-1, -1, -1, -1, -1, -1,
+ retainable ? -1 : -2,
+ retainable ? -1 : -2);
+ }
+
/**
* Creates a new ArrayByteBufferPool with the given configuration.
* Both {@code maxHeapMemory} and {@code maxDirectMemory} default to 0 to use default heuristic.
@@ -67,7 +79,7 @@ public ArrayByteBufferPool()
*/
public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity)
{
- this(minCapacity, factor, maxCapacity, -1, 0, 0);
+ this(minCapacity, factor, maxCapacity, -1, -1, -1);
}
/**
@@ -81,7 +93,7 @@ public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity)
*/
public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity, int maxQueueLength)
{
- this(minCapacity, factor, maxCapacity, maxQueueLength, 0, 0);
+ this(minCapacity, factor, maxCapacity, maxQueueLength, -1, -1);
}
/**
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPool.java
index 90411f155da5..9d1069278ec4 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPool.java
@@ -110,13 +110,13 @@ protected ArrayRetainableByteBufferPool(int minCapacity, int factor, int maxCapa
{
if (minCapacity <= 0)
minCapacity = 0;
+ factor = factor <= 0 ? AbstractByteBufferPool.DEFAULT_FACTOR : factor;
if (maxCapacity <= 0)
- maxCapacity = 64 * 1024;
-
- int f = factor <= 0 ? 4096 : factor;
- if ((maxCapacity % f) != 0 || f >= maxCapacity)
- throw new IllegalArgumentException(String.format("The capacity factor(%d) must be a divisor of maxCapacity(%d)", f, maxCapacity));
+ maxCapacity = AbstractByteBufferPool.DEFAULT_MAX_CAPACITY_BY_FACTOR * factor;
+ if ((maxCapacity % factor) != 0 || factor >= maxCapacity)
+ throw new IllegalArgumentException(String.format("The capacity factor(%d) must be a divisor of maxCapacity(%d)", factor, maxCapacity));
+ int f = factor;
if (bucketIndexFor == null)
bucketIndexFor = c -> (c - 1) / f;
if (bucketCapacity == null)
@@ -136,8 +136,8 @@ protected ArrayRetainableByteBufferPool(int minCapacity, int factor, int maxCapa
_maxCapacity = maxCapacity;
_direct = directArray;
_indirect = indirectArray;
- _maxHeapMemory = (maxHeapMemory != 0L) ? maxHeapMemory : Runtime.getRuntime().maxMemory() / 4;
- _maxDirectMemory = (maxDirectMemory != 0L) ? maxDirectMemory : Runtime.getRuntime().maxMemory() / 4;
+ _maxHeapMemory = AbstractByteBufferPool.retainedSize(maxHeapMemory);
+ _maxDirectMemory = AbstractByteBufferPool.retainedSize(maxDirectMemory);
_bucketIndexFor = bucketIndexFor;
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
index 957d9f725246..4cf0f4298507 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
@@ -241,7 +241,7 @@ public void testClearUnlinksLeakedBuffers()
pool.acquire(10, true);
assertThat(pool.getDirectByteBufferCount(), is(2L));
- assertThat(pool.getDirectMemory(), is(2048L));
+ assertThat(pool.getDirectMemory(), is(2L * AbstractByteBufferPool.DEFAULT_FACTOR));
assertThat(pool.getAvailableDirectByteBufferCount(), is(0L));
assertThat(pool.getAvailableDirectMemory(), is(0L));
@@ -285,16 +285,16 @@ public void testAcquireRelease()
{
RetainableByteBuffer buf1 = pool.acquire(10, true);
assertThat(buf1, is(notNullValue()));
- assertThat(buf1.capacity(), is(1024));
+ assertThat(buf1.capacity(), is(AbstractByteBufferPool.DEFAULT_FACTOR));
RetainableByteBuffer buf2 = pool.acquire(10, true);
assertThat(buf2, is(notNullValue()));
- assertThat(buf2.capacity(), is(1024));
+ assertThat(buf2.capacity(), is(AbstractByteBufferPool.DEFAULT_FACTOR));
buf1.release();
buf2.release();
RetainableByteBuffer buf3 = pool.acquire(16384 + 1, true);
assertThat(buf3, is(notNullValue()));
- assertThat(buf3.capacity(), is(16384 + 1024));
+ assertThat(buf3.capacity(), is(16384 + AbstractByteBufferPool.DEFAULT_FACTOR));
buf3.release();
RetainableByteBuffer buf4 = pool.acquire(32768, true);
@@ -310,7 +310,7 @@ public void testAcquireRelease()
assertThat(pool.getDirectByteBufferCount(), is(4L));
assertThat(pool.getHeapByteBufferCount(), is(1L));
- assertThat(pool.getDirectMemory(), is(1024 + 1024 + 16384 + 1024 + 32768L));
+ assertThat(pool.getDirectMemory(), is(AbstractByteBufferPool.DEFAULT_FACTOR * 3L + 16384 + 32768L));
assertThat(pool.getHeapMemory(), is(32768L));
pool.clear();
From cb8b422f3f3dd006cca0a0349da53903b909c0d8 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Tue, 28 Jun 2022 15:20:38 +1000
Subject: [PATCH 13/24] Combined ByteBufferPool
@#$&!*#*@@ JPMS @!#(*@!%$)*()_!!!
Signed-off-by: Greg Wilkins
---
.../org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
index 4cf0f4298507..fc1adf863f1c 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
@@ -419,7 +419,5 @@ void testLogarithmic()
RetainableByteBuffer retain9 = retainablePool.acquire(9, false);
assertThat(retain9, not(sameInstance(retain5)));
retain9.release();
-
- System.err.println(pool.dump());
}
}
From 1877f39693544c6f3976b8471f5da8cacec5327a Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 29 Jun 2022 09:53:25 +1000
Subject: [PATCH 14/24] Combined ByteBufferPool
Avoid double bean add.
Signed-off-by: Greg Wilkins
---
.../main/java/org/eclipse/jetty/server/AbstractConnector.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
index e538ed78fe29..f3ab9f8d219c 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -204,9 +204,7 @@ public AbstractConnector(
addBean(pool, true);
}
}
-
_byteBufferPool = pool;
- addBean(_byteBufferPool, pool == null);
addEventListener(new Container.Listener()
{
From 0dbf44f501c6dd02a2734878b2c2efeb80abbf4d Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 29 Jun 2022 10:09:43 +1000
Subject: [PATCH 15/24] Combined ByteBufferPool
Updates from review
Signed-off-by: Greg Wilkins
---
.../config/etc/jetty-bytebufferpool-logarithmic.xml | 2 +-
.../src/main/config/etc/jetty-bytebufferpool.xml | 2 +-
.../main/config/modules/bytebufferpool-logarithmic.mod | 8 ++++----
.../src/main/config/modules/bytebufferpool.mod | 10 +++++-----
4 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/jetty-server/src/main/config/etc/jetty-bytebufferpool-logarithmic.xml b/jetty-server/src/main/config/etc/jetty-bytebufferpool-logarithmic.xml
index 4d1fb5039321..39a1e58911c9 100644
--- a/jetty-server/src/main/config/etc/jetty-bytebufferpool-logarithmic.xml
+++ b/jetty-server/src/main/config/etc/jetty-bytebufferpool-logarithmic.xml
@@ -4,7 +4,7 @@
-
+
diff --git a/jetty-server/src/main/config/etc/jetty-bytebufferpool.xml b/jetty-server/src/main/config/etc/jetty-bytebufferpool.xml
index d9004974f0c5..ff09a4b35a10 100644
--- a/jetty-server/src/main/config/etc/jetty-bytebufferpool.xml
+++ b/jetty-server/src/main/config/etc/jetty-bytebufferpool.xml
@@ -5,7 +5,7 @@
-
+
diff --git a/jetty-server/src/main/config/modules/bytebufferpool-logarithmic.mod b/jetty-server/src/main/config/modules/bytebufferpool-logarithmic.mod
index 2243cda0916b..a54485b06f27 100644
--- a/jetty-server/src/main/config/modules/bytebufferpool-logarithmic.mod
+++ b/jetty-server/src/main/config/modules/bytebufferpool-logarithmic.mod
@@ -20,8 +20,8 @@ etc/jetty-bytebufferpool-logarithmic.xml
## Maximum capacity to pool ByteBuffers
#jetty.byteBufferPool.maxCapacity=65536
-## Maximum queue length for each bucket (-1 for unbounded)
-#jetty.byteBufferPool.maxQueueLength=-1
+## Maximum size for each bucket (-1 for unbounded)
+#jetty.byteBufferPool.maxBucketSize=-1
## Maximum heap memory held idle by the pool (0 for heuristic, -1 for unlimited).
#jetty.byteBufferPool.maxHeapMemory=0
@@ -29,8 +29,8 @@ etc/jetty-bytebufferpool-logarithmic.xml
## Maximum direct memory held idle by the pool (0 for heuristic, -1 for unlimited).
#jetty.byteBufferPool.maxDirectMemory=0
-## Maximum heap memory retained whilst in use by the pool (0 for heuristic, -1 for unlimited).
+## Maximum heap memory retained whilst in use by the pool (0 for heuristic, -1 for unlimited, -2 for no retained).
#jetty.byteBufferPool.retainedHeapMemory=0
-## Maximum direct memory retained whilst in use by the pool (0 for heuristic, -1 for unlimited).
+## Maximum direct memory retained whilst in use by the pool (0 for heuristic, -1 for unlimited, -2 for no retained).
#jetty.byteBufferPool.retainedDirectMemory=0
diff --git a/jetty-server/src/main/config/modules/bytebufferpool.mod b/jetty-server/src/main/config/modules/bytebufferpool.mod
index f229fb7eeb36..2f651024f573 100644
--- a/jetty-server/src/main/config/modules/bytebufferpool.mod
+++ b/jetty-server/src/main/config/modules/bytebufferpool.mod
@@ -1,6 +1,6 @@
[description]
Configures the ByteBufferPool used by ServerConnectors.
-Use module "bytebufferpool-logarithmic" for a more space efficient pool.
+Use module "bytebufferpool-logarithmic" for a pool may hold less granulated sized buffers.
[tags]
bytebufferpool
@@ -22,8 +22,8 @@ etc/jetty-bytebufferpool.xml
## a capacity that is multiple of this factor.
#jetty.byteBufferPool.factor=1024
-## Maximum queue length for each bucket (-1 for unbounded).
-#jetty.byteBufferPool.maxQueueLength=-1
+## Maximum size for each bucket (-1 for unbounded).
+#jetty.byteBufferPool.maxBucketSize=-1
## Maximum heap memory held idle by the pool (0 for heuristic, -1 for unlimited).
#jetty.byteBufferPool.maxHeapMemory=0
@@ -31,8 +31,8 @@ etc/jetty-bytebufferpool.xml
## Maximum direct memory held idle by the pool (0 for heuristic, -1 for unlimited).
#jetty.byteBufferPool.maxDirectMemory=0
-## Maximum heap memory retained whilst in use by the pool (0 for heuristic, -1 for unlimited).
+## Maximum heap memory retained whilst in use by the pool (0 for heuristic, -1 for unlimited, -2 for no retained).
#jetty.byteBufferPool.retainedHeapMemory=0
-## Maximum direct memory retained whilst in use by the pool (0 for heuristic, -1 for unlimited).
+## Maximum direct memory retained whilst in use by the pool (0 for heuristic, -1 for unlimited, -2 for no retained).
#jetty.byteBufferPool.retainedDirectMemory=0
\ No newline at end of file
From c5c0ca90faaad9db1a1fb53658982abfbc5bf053 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 29 Jun 2022 10:13:01 +1000
Subject: [PATCH 16/24] Combined ByteBufferPool
Fixed JPMS issue
Signed-off-by: Greg Wilkins
---
.../eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
index fc1adf863f1c..637429c6a588 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayRetainableByteBufferPoolTest.java
@@ -396,7 +396,7 @@ public void testEndiannessResetOnRelease()
}
@Test
- void testLogarithmic()
+ public void testLogarithmic()
{
LogarithmicArrayByteBufferPool pool = new LogarithmicArrayByteBufferPool();
ByteBuffer buffer5 = pool.acquire(5, false);
@@ -413,7 +413,6 @@ void testLogarithmic()
RetainableByteBuffer retain5 = retainablePool.acquire(5, false);
retain5.release();
RetainableByteBuffer retain6 = retainablePool.acquire(6, false);
- System.err.println(pool.dump());
assertThat(retain6, sameInstance(retain5));
retain6.release();
RetainableByteBuffer retain9 = retainablePool.acquire(9, false);
From 5c4abfad6e7a6182d2b5536372adf9d93a6a2d64 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 29 Jun 2022 11:01:50 +1000
Subject: [PATCH 17/24] Combined ByteBufferPool
Fixed async IO write test
Signed-off-by: Greg Wilkins
---
.../jetty/server/AbstractConnector.java | 3 +-
.../jetty/server/AsyncCompletionTest.java | 49 ++++++++-----------
2 files changed, 23 insertions(+), 29 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
index f3ab9f8d219c..932e852a4e21 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -34,6 +34,7 @@
import org.eclipse.jetty.io.ArrayByteBufferPool;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.LogarithmicArrayByteBufferPool;
import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.StringUtil;
@@ -194,7 +195,7 @@ public AbstractConnector(
pool = server.getBean(ByteBufferPool.class);
if (pool == null)
{
- pool = new ArrayByteBufferPool();
+ pool = new LogarithmicArrayByteBufferPool();
server.addBean(pool, true);
}
addBean(pool, false);
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncCompletionTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncCompletionTest.java
index d5703e09baee..997f0b383462 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncCompletionTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncCompletionTest.java
@@ -210,46 +210,39 @@ public void testAsyncIOWrite(AsyncIOWriteHandler handler) throws Exception
os.write("GET / HTTP/1.0\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1));
os.flush();
- // wait for OWP to execute (proves we do not block in write APIs)
- boolean completeCalled = handler.waitForOWPExit();
-
while (true)
{
- // wait for threads to return to base level (proves we are really async)
+ PendingCallback delay = __queue.poll(POLL, TimeUnit.MILLISECONDS);
+ Boolean owpExit = handler.pollForOWPExit();
+ if (owpExit == null)
+ {
+ // handle any callback written so far
+ while (delay != null)
+ {
+ delay.proceed();
+ delay = __queue.poll(POLL, TimeUnit.MILLISECONDS);
+ }
+ continue;
+ }
+
+ // OWP has exited, but we have a delay, so let's wait for thread to return to the pool to ensure we are async.
long end = System.nanoTime() + TimeUnit.SECONDS.toNanos(WAIT);
- while (_threadPool.getBusyThreads() != base)
+ while (delay != null && _threadPool.getBusyThreads() > base)
{
if (System.nanoTime() > end)
throw new TimeoutException();
Thread.sleep(POLL);
}
- if (completeCalled)
- break;
-
- // We are now asynchronously waiting!
- assertThat(__transportComplete.get(), is(false));
-
- // If we are not complete, we must be waiting for one or more writes to complete
- while (true)
+ // handle any callback written so far
+ while (delay != null)
{
- PendingCallback delay = __queue.poll(POLL, TimeUnit.MILLISECONDS);
- if (delay != null)
- {
- delay.proceed();
- continue;
- }
- // No delay callback found, have we finished OWP again?
- Boolean c = handler.pollForOWPExit();
-
- if (c == null)
- // No we haven't, so look for another delay callback
- continue;
+ delay.proceed();
+ delay = __queue.poll(POLL, TimeUnit.MILLISECONDS);
+ }
- // We have a OWP result, so let's handle it.
- completeCalled = c;
+ if (owpExit)
break;
- }
}
// Wait for full completion
From b61d133ee711d21df5f8542ec954c3a0c51b8811 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 29 Jun 2022 11:29:55 +1000
Subject: [PATCH 18/24] Combined ByteBufferPool
Fixed BufferedResponseHandlerTest
Signed-off-by: Greg Wilkins
---
.../jetty/server/handler/BufferedResponseHandlerTest.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/BufferedResponseHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/BufferedResponseHandlerTest.java
index b4072cf28afe..906d09ad528b 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/BufferedResponseHandlerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/BufferedResponseHandlerTest.java
@@ -19,6 +19,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.io.NullByteBufferPool;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.LocalConnector;
@@ -49,6 +50,7 @@ public class BufferedResponseHandlerTest
public static void setUp() throws Exception
{
_server = new Server();
+ _server.addBean(new NullByteBufferPool()); // Avoid giving larger buffers than requested
_config = new HttpConfiguration();
_config.setOutputBufferSize(1024);
_config.setOutputAggregationSize(256);
From 9e1cf323129832e78e30d29e205e917d808cfe7e Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 29 Jun 2022 13:11:05 +1000
Subject: [PATCH 19/24] Combined ByteBufferPool
Fixed more tests
Signed-off-by: Greg Wilkins
---
.../jetty/client/HttpClientTLSTest.java | 69 ++++++++++++++++---
.../eclipse/jetty/io/ArrayByteBufferPool.java | 4 +-
.../jetty/io/RetainableByteBufferPool.java | 7 ++
3 files changed, 68 insertions(+), 12 deletions(-)
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java
index e4d5358cf78d..c715ac5caa0f 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java
@@ -708,6 +708,54 @@ protected int networkFill(ByteBuffer input) throws IOException
assertEquals(0, clientBytes.get());
}
+ protected class TestRetained extends ArrayRetainableByteBufferPool
+ {
+ private final ByteBufferPool _pool;
+
+ public TestRetained(ByteBufferPool pool, int factor, int maxCapacity, int maxBucketSize, long retainedHeapMemory, long retainedDirectMemory)
+ {
+ super(0, factor, maxCapacity, maxBucketSize, retainedHeapMemory, retainedDirectMemory);
+ _pool = pool;
+ }
+
+ @Override
+ protected ByteBuffer allocate(int capacity)
+ {
+ System.err.println("allocate " + capacity);
+ new Throwable().printStackTrace();
+ return _pool.acquire(capacity, false);
+ }
+
+ @Override
+ protected ByteBuffer allocateDirect(int capacity)
+ {
+ System.err.println("allocateDirect " + capacity);
+ new Throwable().printStackTrace();
+ return _pool.acquire(capacity, true);
+ }
+
+ @Override
+ protected void removed(RetainableByteBuffer retainedBuffer)
+ {
+ _pool.release(retainedBuffer.getBuffer());
+ }
+
+ @Override
+ public Pool poolFor(int capacity, boolean direct)
+ {
+ return super.poolFor(capacity, direct);
+ }
+ }
+
+ private class TestByteBufferPool extends ArrayByteBufferPool
+ {
+ @Override
+ protected RetainableByteBufferPool newRetainableByteBufferPool(int factor, int maxCapacity, int maxBucketSize, long retainedHeapMemory, long retainedDirectMemory)
+ {
+ return new TestRetained(this, factor, maxCapacity, maxBucketSize, retainedHeapMemory, retainedDirectMemory);
+ }
+ }
+
@Test
public void testEncryptedInputBufferRepooling() throws Exception
{
@@ -715,15 +763,10 @@ public void testEncryptedInputBufferRepooling() throws Exception
QueuedThreadPool serverThreads = new QueuedThreadPool();
serverThreads.setName("server");
server = new Server(serverThreads);
- var retainableByteBufferPool = new ArrayRetainableByteBufferPool()
- {
- @Override
- public Pool poolFor(int capacity, boolean direct)
- {
- return super.poolFor(capacity, direct);
- }
- };
- server.addBean(retainableByteBufferPool);
+
+ ArrayByteBufferPool byteBufferPool = new TestByteBufferPool();
+ RetainableByteBufferPool retainableByteBufferPool = byteBufferPool.asRetainableByteBufferPool();
+ server.addBean(byteBufferPool);
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.addCustomizer(new SecureRequestCustomizer());
HttpConnectionFactory http = new HttpConnectionFactory(httpConfig);
@@ -765,9 +808,12 @@ protected int networkFill(ByteBuffer input) throws IOException
assertThrows(Exception.class, () -> client.newRequest("localhost", connector.getLocalPort()).scheme(HttpScheme.HTTPS.asString()).send());
- Pool bucket = retainableByteBufferPool.poolFor(16 * 1024 + 1, ssl.isDirectBuffersForEncryption());
+ Pool bucket = ((TestRetained)retainableByteBufferPool).poolFor(16 * 1024 + 1, connector.getConnectionFactory(HttpConnectionFactory.class).isUseInputDirectByteBuffers());
assertEquals(1, bucket.size());
assertEquals(1, bucket.getIdleCount());
+
+ long count = ssl.isDirectBuffersForDecryption() ? byteBufferPool.getDirectByteBufferCount() : byteBufferPool.getHeapByteBufferCount();
+ assertEquals(1, count);
}
@Test
@@ -834,6 +880,7 @@ protected boolean networkFlush(ByteBuffer output) throws IOException
assertThrows(Exception.class, () -> client.newRequest("localhost", connector.getLocalPort()).scheme(HttpScheme.HTTPS.asString()).send());
+ byteBufferPool.asRetainableByteBufferPool().clear();
await().atMost(5, TimeUnit.SECONDS).until(() -> leakedBuffers, is(empty()));
}
@@ -916,6 +963,7 @@ protected void service(String target, Request jettyRequest, HttpServletRequest r
assertThrows(Exception.class, () -> client.newRequest("localhost", connector.getLocalPort()).scheme(HttpScheme.HTTPS.asString()).send());
+ byteBufferPool.asRetainableByteBufferPool().clear();
await().atMost(5, TimeUnit.SECONDS).until(() -> leakedBuffers, is(empty()));
}
@@ -998,6 +1046,7 @@ protected void service(String target, Request jettyRequest, HttpServletRequest r
assertThrows(Exception.class, () -> client.newRequest("localhost", connector.getLocalPort()).scheme(HttpScheme.HTTPS.asString()).send());
+ byteBufferPool.asRetainableByteBufferPool().clear();
await().atMost(5, TimeUnit.SECONDS).until(() -> leakedBuffers, is(empty()));
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
index 8ff571d550bf..f10297a07a89 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
@@ -244,7 +244,7 @@ protected int capacityFor(int bucket)
return bucket * getCapacityFactor();
}
- private Bucket bucketFor(int capacity, boolean direct)
+ protected Bucket bucketFor(int capacity, boolean direct)
{
if (capacity < _minCapacity)
return null;
@@ -327,7 +327,7 @@ public String toString()
protected class Retained extends ArrayRetainableByteBufferPool
{
- Retained(int factor, int maxCapacity, int maxBucketSize, long retainedHeapMemory, long retainedDirectMemory)
+ public Retained(int factor, int maxCapacity, int maxBucketSize, long retainedHeapMemory, long retainedDirectMemory)
{
super(0, factor, maxCapacity, maxBucketSize, retainedHeapMemory, retainedDirectMemory);
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/RetainableByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/RetainableByteBufferPool.java
index 0831bb636c84..c6393c18c370 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/RetainableByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/RetainableByteBufferPool.java
@@ -30,6 +30,8 @@ public interface RetainableByteBufferPool
*/
RetainableByteBuffer acquire(int size, boolean direct);
+ void clear();
+
static RetainableByteBufferPool from(ByteBufferPool byteBufferPool)
{
return new RetainableByteBufferPool()
@@ -48,6 +50,11 @@ private void release(RetainableByteBuffer retainedBuffer)
byteBufferPool.release(retainedBuffer.getBuffer());
}
+ @Override
+ public void clear()
+ {
+ }
+
@Override
public String toString()
{
From 78edb9cbb94a9cebb1bf0fd58f734796cc0ed1a6 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 29 Jun 2022 14:10:48 +1000
Subject: [PATCH 20/24] Combined ByteBufferPool
Fixed FastCGI that was expecting a larger buffer than requested
Signed-off-by: Greg Wilkins
---
.../java/org/eclipse/jetty/fcgi/generator/ServerGenerator.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ServerGenerator.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ServerGenerator.java
index 132a2823171b..cd75698f92c1 100644
--- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ServerGenerator.java
+++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ServerGenerator.java
@@ -120,7 +120,7 @@ public Result generateResponseContent(int request, ByteBuffer content, boolean l
private ByteBuffer generateEndRequest(int request, boolean aborted)
{
request &= 0xFF_FF;
- ByteBuffer endRequestBuffer = acquire(8);
+ ByteBuffer endRequestBuffer = acquire(16);
BufferUtil.clearToFill(endRequestBuffer);
endRequestBuffer.putInt(0x01_03_00_00 + request);
endRequestBuffer.putInt(0x00_08_00_00);
From 80ac54712b2d2f2b3d8d6036fd795c39154903a7 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 29 Jun 2022 15:43:02 +1000
Subject: [PATCH 21/24] Combined ByteBufferPool
minor cleanups
Signed-off-by: Greg Wilkins
---
.../main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java | 6 +++---
jetty-server/src/main/config/etc/jetty-bytebufferpool.xml | 2 +-
jetty-server/src/main/config/modules/bytebufferpool.mod | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
index f10297a07a89..f63dd5b58a68 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
@@ -31,9 +31,9 @@
/**
* A ByteBuffer pool where ByteBuffers are held in queues that are held in array elements.
- * Given a capacity {@code factor} of 1024, the first array element holds a queue of ByteBuffers
- * each of capacity 1024, the second array element holds a queue of ByteBuffers each of capacity
- * 2048, and so on.
+ * Given a capacity {@code factor} of 4096, the first array element holds a bucket of ByteBuffers
+ * each of capacity 4096, the second array element holds a bucket of ByteBuffers each of capacity
+ * 8192, and so on.
* The {@code maxHeapMemory} and {@code maxDirectMemory} default heuristic is to use {@link Runtime#maxMemory()}
* divided by 4.
*/
diff --git a/jetty-server/src/main/config/etc/jetty-bytebufferpool.xml b/jetty-server/src/main/config/etc/jetty-bytebufferpool.xml
index ff09a4b35a10..f1d787a62018 100644
--- a/jetty-server/src/main/config/etc/jetty-bytebufferpool.xml
+++ b/jetty-server/src/main/config/etc/jetty-bytebufferpool.xml
@@ -3,7 +3,7 @@
-
+
diff --git a/jetty-server/src/main/config/modules/bytebufferpool.mod b/jetty-server/src/main/config/modules/bytebufferpool.mod
index 2f651024f573..97e8b5217cfd 100644
--- a/jetty-server/src/main/config/modules/bytebufferpool.mod
+++ b/jetty-server/src/main/config/modules/bytebufferpool.mod
@@ -20,7 +20,7 @@ etc/jetty-bytebufferpool.xml
## Bucket capacity factor.
## ByteBuffers are allocated out of buckets that have
## a capacity that is multiple of this factor.
-#jetty.byteBufferPool.factor=1024
+#jetty.byteBufferPool.factor=4096
## Maximum size for each bucket (-1 for unbounded).
#jetty.byteBufferPool.maxBucketSize=-1
@@ -35,4 +35,4 @@ etc/jetty-bytebufferpool.xml
#jetty.byteBufferPool.retainedHeapMemory=0
## Maximum direct memory retained whilst in use by the pool (0 for heuristic, -1 for unlimited, -2 for no retained).
-#jetty.byteBufferPool.retainedDirectMemory=0
\ No newline at end of file
+#jetty.byteBufferPool.retainedDirectMemory=0
From c2d261efb0637b329972eecabf50654f920db8e3 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Fri, 1 Jul 2022 08:28:11 +1000
Subject: [PATCH 22/24] Combined ByteBufferPool
Updates from review
Signed-off-by: Greg Wilkins
---
.../java/org/eclipse/jetty/io/AbstractByteBufferPool.java | 4 ++--
.../main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java | 4 ++--
.../main/java/org/eclipse/jetty/io/NullByteBufferPool.java | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java
index 544825e0adf0..e4aca8c0f079 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java
@@ -34,8 +34,8 @@
@ManagedObject
abstract class AbstractByteBufferPool implements ByteBufferPool
{
- public static final Integer DEFAULT_FACTOR = 4096;
- public static final Integer DEFAULT_MAX_CAPACITY_BY_FACTOR = 16;
+ public static final int DEFAULT_FACTOR = 4096;
+ public static final int DEFAULT_MAX_CAPACITY_BY_FACTOR = 16;
private final int _factor;
private final int _maxCapacity;
private final int _maxBucketSize;
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
index f63dd5b58a68..c0fdd5a27801 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
@@ -79,7 +79,7 @@ public ArrayByteBufferPool(boolean retainable)
*/
public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity)
{
- this(minCapacity, factor, maxCapacity, -1, -1, -1);
+ this(minCapacity, factor, maxCapacity, -1, 0, 0);
}
/**
@@ -93,7 +93,7 @@ public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity)
*/
public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity, int maxQueueLength)
{
- this(minCapacity, factor, maxCapacity, maxQueueLength, -1, -1);
+ this(minCapacity, factor, maxCapacity, maxQueueLength, 0, 0);
}
/**
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/NullByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/NullByteBufferPool.java
index 88ab24651f68..cb06a1014769 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/NullByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/NullByteBufferPool.java
@@ -19,7 +19,7 @@
public class NullByteBufferPool implements ByteBufferPool
{
- private RetainableByteBufferPool _retainableByteBufferPool = RetainableByteBufferPool.from(this);
+ private final RetainableByteBufferPool _retainableByteBufferPool = RetainableByteBufferPool.from(this);
@Override
public ByteBuffer acquire(int size, boolean direct)
From 02bc66d361b8c2514e0ec51135f706ed4eb9ca11 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Fri, 1 Jul 2022 08:36:19 +1000
Subject: [PATCH 23/24] Combined ByteBufferPool
Updates from review
Signed-off-by: Greg Wilkins
---
.../jetty/io/MappedByteBufferPool.java | 30 +++++++++----------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java
index 4ac8f482e568..fb5c55738df4 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/MappedByteBufferPool.java
@@ -69,67 +69,67 @@ public MappedByteBufferPool(int factor)
* Creates a new MappedByteBufferPool with the given configuration.
*
* @param factor the capacity factor
- * @param maxQueueLength the maximum ByteBuffer queue length
+ * @param maxBucketSize the maximum ByteBuffer bucket size
*/
- public MappedByteBufferPool(int factor, int maxQueueLength)
+ public MappedByteBufferPool(int factor, int maxBucketSize)
{
- this(factor, maxQueueLength, null);
+ this(factor, maxBucketSize, null);
}
/**
* Creates a new MappedByteBufferPool with the given configuration.
*
* @param factor the capacity factor
- * @param maxQueueLength the maximum ByteBuffer queue length
+ * @param maxBucketSize the maximum ByteBuffer bucket size
* @param newBucket the function that creates a Bucket
*/
- private MappedByteBufferPool(int factor, int maxQueueLength, Function newBucket)
+ private MappedByteBufferPool(int factor, int maxBucketSize, Function newBucket)
{
- this(factor, maxQueueLength, newBucket, -1, -1, -1, -1);
+ this(factor, maxBucketSize, newBucket, 0, 0, 0, 0);
}
/**
* Creates a new MappedByteBufferPool with the given configuration.
*
* @param factor the capacity factor
- * @param maxQueueLength the maximum ByteBuffer queue length
+ * @param maxBucketSize the maximum ByteBuffer bucket size
* @param maxHeapMemory the max heap memory in bytes, -1 for unlimited memory or 0 to use default heuristic.
* @param maxDirectMemory the max direct memory in bytes, -1 for unlimited memory or 0 to use default heuristic.
*/
- public MappedByteBufferPool(int factor, int maxQueueLength, long maxHeapMemory, long maxDirectMemory)
+ public MappedByteBufferPool(int factor, int maxBucketSize, long maxHeapMemory, long maxDirectMemory)
{
- this(factor, maxQueueLength, null, maxHeapMemory, maxDirectMemory, maxHeapMemory, maxDirectMemory);
+ this(factor, maxBucketSize, null, maxHeapMemory, maxDirectMemory, maxHeapMemory, maxDirectMemory);
}
/**
* Creates a new MappedByteBufferPool with the given configuration.
*
* @param factor the capacity factor
- * @param maxQueueLength the maximum ByteBuffer queue length
+ * @param maxBucketSize the maximum ByteBuffer bucket size
* @param maxHeapMemory the max heap memory in bytes, -1 for unlimited memory or 0 to use default heuristic.
* @param maxDirectMemory the max direct memory in bytes, -1 for unlimited memory or 0 to use default heuristic.
* @param retainedHeapMemory the max heap memory in bytes, -2 for no retained memory, -1 for unlimited retained memory or 0 to use default heuristic
* @param retainedDirectMemory the max direct memory in bytes, -2 for no retained memory, -1 for unlimited retained memory or 0 to use default heuristic
*/
- public MappedByteBufferPool(int factor, int maxQueueLength, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
+ public MappedByteBufferPool(int factor, int maxBucketSize, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
{
- this(factor, maxQueueLength, null, maxHeapMemory, maxDirectMemory, retainedHeapMemory, retainedDirectMemory);
+ this(factor, maxBucketSize, null, maxHeapMemory, maxDirectMemory, retainedHeapMemory, retainedDirectMemory);
}
/**
* Creates a new MappedByteBufferPool with the given configuration.
*
* @param factor the capacity factor
- * @param maxQueueLength the maximum ByteBuffer queue length
+ * @param maxBucketSize the maximum ByteBuffer bucket size
* @param newBucket the function that creates a Bucket
* @param maxHeapMemory the max heap memory in bytes, -1 for unlimited memory or 0 to use default heuristic.
* @param maxDirectMemory the max direct memory in bytes, -1 for unlimited memory or 0 to use default heuristic.
* @param retainedHeapMemory the max heap memory in bytes, -2 for no retained memory, -1 for unlimited retained memory or 0 to use default heuristic
* @param retainedDirectMemory the max direct memory in bytes, -2 for no retained memory, -1 for unlimited retained memory or 0 to use default heuristic
*/
- private MappedByteBufferPool(int factor, int maxQueueLength, Function newBucket, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
+ private MappedByteBufferPool(int factor, int maxBucketSize, Function newBucket, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
{
- super(factor, 0, maxQueueLength, maxHeapMemory, maxDirectMemory, retainedHeapMemory, retainedDirectMemory);
+ super(factor, 0, maxBucketSize, maxHeapMemory, maxDirectMemory, retainedHeapMemory, retainedDirectMemory);
_newBucket = newBucket;
}
From 0cfc50cd4d24e5418975fd3b5fbb17baccf00072 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Sat, 2 Jul 2022 15:11:15 +1000
Subject: [PATCH 24/24] Combined ByteBufferPool
Updates from review
Signed-off-by: Greg Wilkins
---
.../org/eclipse/jetty/client/HttpClientTLSTest.java | 12 ++++--------
.../org/eclipse/jetty/io/ArrayByteBufferPool.java | 12 ------------
2 files changed, 4 insertions(+), 20 deletions(-)
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java
index c715ac5caa0f..14fc9994c3f6 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java
@@ -22,9 +22,9 @@
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
@@ -721,16 +721,12 @@ public TestRetained(ByteBufferPool pool, int factor, int maxCapacity, int maxBuc
@Override
protected ByteBuffer allocate(int capacity)
{
- System.err.println("allocate " + capacity);
- new Throwable().printStackTrace();
return _pool.acquire(capacity, false);
}
@Override
protected ByteBuffer allocateDirect(int capacity)
{
- System.err.println("allocateDirect " + capacity);
- new Throwable().printStackTrace();
return _pool.acquire(capacity, true);
}
@@ -823,7 +819,7 @@ public void testEncryptedOutputBufferRepooling() throws Exception
QueuedThreadPool serverThreads = new QueuedThreadPool();
serverThreads.setName("server");
server = new Server(serverThreads);
- List leakedBuffers = new ArrayList<>();
+ List leakedBuffers = new CopyOnWriteArrayList<>();
ArrayByteBufferPool byteBufferPool = new ArrayByteBufferPool()
{
@Override
@@ -892,7 +888,7 @@ public void testEncryptedOutputBufferRepoolingAfterNetworkFlushReturnsFalse(bool
QueuedThreadPool serverThreads = new QueuedThreadPool();
serverThreads.setName("server");
server = new Server(serverThreads);
- List leakedBuffers = new ArrayList<>();
+ List leakedBuffers = new CopyOnWriteArrayList<>();
ArrayByteBufferPool byteBufferPool = new ArrayByteBufferPool()
{
@Override
@@ -975,7 +971,7 @@ public void testEncryptedOutputBufferRepoolingAfterNetworkFlushThrows(boolean cl
QueuedThreadPool serverThreads = new QueuedThreadPool();
serverThreads.setName("server");
server = new Server(serverThreads);
- List leakedBuffers = new ArrayList<>();
+ List leakedBuffers = new CopyOnWriteArrayList<>();
ArrayByteBufferPool byteBufferPool = new ArrayByteBufferPool()
{
@Override
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
index c0fdd5a27801..61e407d65845 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
@@ -57,18 +57,6 @@ public ArrayByteBufferPool()
this(-1, -1, -1);
}
- /**
- * Creates a new ArrayByteBufferPool with a default configuration.
- * Both {@code maxHeapMemory} and {@code maxDirectMemory} default to 0 to use default heuristic.
- * @param retainable True if {@link #asRetainableByteBufferPool()} return a real implementation.
- */
- public ArrayByteBufferPool(boolean retainable)
- {
- this(-1, -1, -1, -1, -1, -1,
- retainable ? -1 : -2,
- retainable ? -1 : -2);
- }
-
/**
* Creates a new ArrayByteBufferPool with the given configuration.
* Both {@code maxHeapMemory} and {@code maxDirectMemory} default to 0 to use default heuristic.