Skip to content

Commit 0f21574

Browse files
core: reduce CompositeReadableBuffer allocation (#3279)
* core: reduce CompositeReadableBuffer allocation Add ability for CompositeReadableBuffer read specified length bytes to another CompositeReadableBuffer instead of create temp CompositeReadableBuffer. fixes #3278 --------- Co-authored-by: Larry Safran <[email protected]>
1 parent 846e008 commit 0f21574

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

core/src/main/java/io/grpc/internal/CompositeReadableBuffer.java

+27
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.nio.InvalidMarkException;
2424
import java.util.ArrayDeque;
2525
import java.util.Deque;
26+
import java.util.Queue;
2627
import javax.annotation.Nullable;
2728

2829
/**
@@ -38,6 +39,7 @@ public class CompositeReadableBuffer extends AbstractReadableBuffer {
3839
private final Deque<ReadableBuffer> readableBuffers;
3940
private Deque<ReadableBuffer> rewindableBuffers;
4041
private int readableBytes;
42+
private final Queue<ReadableBuffer> buffers = new ArrayDeque<ReadableBuffer>(2);
4143
private boolean marked;
4244

4345
public CompositeReadableBuffer(int initialCapacity) {
@@ -159,6 +161,31 @@ public void readBytes(OutputStream dest, int length) throws IOException {
159161
execute(STREAM_OP, length, dest, 0);
160162
}
161163

164+
/**
165+
* Reads {@code length} bytes from this buffer and writes them to the destination buffer.
166+
* Increments the read position by {@code length}. If the required bytes are not readable, throws
167+
* {@link IndexOutOfBoundsException}.
168+
*
169+
* @param dest the destination buffer to receive the bytes.
170+
* @param length the number of bytes to be copied.
171+
* @throws IndexOutOfBoundsException if required bytes are not readable
172+
*/
173+
public void readBytes(CompositeReadableBuffer dest, int length) {
174+
checkReadable(length);
175+
readableBytes -= length;
176+
177+
while (length > 0) {
178+
ReadableBuffer buffer = buffers.peek();
179+
if (buffer.readableBytes() > length) {
180+
dest.addBuffer(buffer.readBytes(length));
181+
length = 0;
182+
} else {
183+
dest.addBuffer(buffers.poll());
184+
length -= buffer.readableBytes();
185+
}
186+
}
187+
}
188+
162189
@Override
163190
public ReadableBuffer readBytes(int length) {
164191
if (length <= 0) {

0 commit comments

Comments
 (0)