From 07a3ceeb5dc16a09f54b44844091b8a566495244 Mon Sep 17 00:00:00 2001 From: Baoyi Chen Date: Thu, 29 Oct 2020 18:49:09 +0800 Subject: [PATCH] Fix issue #5499 this PR let the ByteAccumulator recyclable. after invoke ByteAccumulator.transferTo method we can invoke ByteAccumulator.recycle method to reuse byte[] via ByteAccumulator.newByteArray method Signed-off-by: Baoyi Chen --- .../extensions/compress/ByteAccumulator.java | 15 +++++----- .../compress/CompressExtension.java | 4 +-- .../compress/ByteAccumulatorTest.java | 28 +++++++++---------- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulator.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulator.java index a92d40d1b476..fb010085696a 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulator.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulator.java @@ -28,10 +28,10 @@ public class ByteAccumulator { - private List chunks = new ArrayList<>(); + private final List chunks = new ArrayList<>(); private final int maxSize; private int length = 0; - private ByteBufferPool bufferPool; + private final ByteBufferPool bufferPool; public ByteAccumulator(int maxOverallBufferSize) { @@ -44,17 +44,18 @@ public ByteAccumulator(int maxOverallBufferSize, ByteBufferPool bufferPool) this.bufferPool = bufferPool; } - public void copyChunk(ByteBuffer buffer, int length) + public void copyChunk(ByteBuffer buffer) { + int length = buffer.position(); if (this.length + length > maxSize) { String err = String.format("Resulting message size [%,d] is too large for configured max of [%,d]", this.length + length, maxSize); throw new MessageTooLargeException(err); } - if (length > 0) + + if (length > 0) { - buffer.limit(length); - chunks.add(buffer); + chunks.add((ByteBuffer) buffer.flip()); this.length += length; } else @@ -124,6 +125,6 @@ void recycle() bufferPool.release(chunk); } - chunks = new ArrayList<>(); + chunks.clear(); } } diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java index dd26bbd3e6c1..47250add1f29 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java @@ -193,12 +193,12 @@ int copyChunk(Inflater inflater, ByteAccumulator accumulator, ByteBuffer buf) th int read = inflater.inflate(buf.array(), position, capacity - position); if (read <= 0) { - accumulator.copyChunk(buf, position); + accumulator.copyChunk((ByteBuffer)buf.position(position)); return read; } position += read; } - accumulator.copyChunk(buf, position); + accumulator.copyChunk((ByteBuffer) buf.position(position)); return position; } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulatorTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulatorTest.java index 452644e4c1ae..e7e44d49fe7e 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulatorTest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/compress/ByteAccumulatorTest.java @@ -103,20 +103,20 @@ public void testRecycle() // 1 ByteBuffer buf = accumulator.newByteBuffer(10); byte[] hello = "Hello".getBytes(UTF_8); - System.arraycopy(hello, 0, buf.array(), 0, hello.length); - accumulator.copyChunk(buf, hello.length); + buf.put(hello); + accumulator.copyChunk(buf); // 2 buf = accumulator.newByteBuffer(10); byte[] space = " ".getBytes(UTF_8); - System.arraycopy(space, 0, buf.array(), 0, space.length); - accumulator.copyChunk(buf, space.length); + buf.put(space); + accumulator.copyChunk(buf); // 3 buf = accumulator.newByteBuffer(10); byte[] world = "World".getBytes(UTF_8); - System.arraycopy(world, 0, buf.array(), 0, world.length); - accumulator.copyChunk(buf, world.length); + buf.put(world); + accumulator.copyChunk(buf); assertThat("Length", accumulator.getLength(), is(hello.length + space.length + world.length)); @@ -130,26 +130,26 @@ public void testRecycle() // 1 ByteBuffer buf = accumulator.newByteBuffer(10); byte[] olleh = "olleH".getBytes(UTF_8); - System.arraycopy(olleh, 0, buf.array(), 0, olleh.length); - accumulator.copyChunk(buf, olleh.length); + buf.put(olleh); + accumulator.copyChunk(buf); // 2 buf = accumulator.newByteBuffer(10); byte[] space = " ".getBytes(UTF_8); - System.arraycopy(space, 0, buf.array(), 0, space.length); - accumulator.copyChunk(buf, space.length); + buf.put(space); + accumulator.copyChunk(buf); // 3 buf = accumulator.newByteBuffer(10); byte[] dlrow = "dlroW".getBytes(UTF_8); - System.arraycopy(dlrow, 0, buf.array(), 0, dlrow.length); - accumulator.copyChunk(buf, dlrow.length); + buf.put(dlrow); + accumulator.copyChunk(buf); // 4 buf = accumulator.newByteBuffer(10); byte[] done = " enoD".getBytes(UTF_8); - System.arraycopy(done, 0, buf.array(), 0, done.length); - accumulator.copyChunk(buf, done.length); + buf.put(done); + accumulator.copyChunk(buf); assertThat("Length", accumulator.getLength(), is(olleh.length + space.length + dlrow.length + done.length));