-
Notifications
You must be signed in to change notification settings - Fork 4k
protobuf: zero copy into protobuf #7250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…g underlying ByteBuffers
…ByteBuffer operation.
…ation supports it.
fe6c132 to
94b5124
Compare
njhill
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@voidzcy thanks, I'm quite interested in this change! I hope you don't mind the flyby comments
| * @throws UnsupportedOperationException the buffer does not support this method | ||
| * @throws IndexOutOfBoundsException if required bytes are not readable | ||
| */ | ||
| List<ByteBuffer> readByteBuffers(int length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about just returning null here instead of separate boolean method? This would also be more efficient for composite case since it means not having to iterate over the buffers an additional time.
| if (buffer.readableBytes() < length) { | ||
| throw new IndexOutOfBoundsException(); | ||
| } | ||
| List<ByteBuffer> res = Arrays.asList(buffer.nioBuffers(buffer.readerIndex(), length)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here would be preferable to do:
List<ByteBuffer> res = buffer.nioBufferCount() == 1
? Collections.singletonList(buffer.nioBuffer(buffer.readableIndex(), length)
: Arrays.asList(buffer.nioBuffers(buffer.readerIndex(), length));| public List<ByteBuffer> readByteBuffers(int length) { | ||
| if (buffer.readableBytes() < length) { | ||
| throw new IndexOutOfBoundsException(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Return empty list here if length == 0?
| // messages. | ||
| if (stream instanceof ByteBufferReadable) { | ||
| cis = CodedInputStream.newInstance( | ||
| ((ByteBufferReadable) stream).readByteBuffers(size)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems the protobuf code doesn't do this itself so would be better to handle (most common) singleton case separately:
List<ByteBuffer> bufs = ((ByteBufferReadable) stream).readByteBuffers(size);
cis = bufs.size() == 1 ? CodedInputStream.newInstance(bufs.get(0)) : CodedInputStream.newInstance(bufs);| * bytes can be read. | ||
| */ | ||
| @Nullable | ||
| Iterable<ByteBuffer> readByteBuffers(int length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe return Collections.emptyList() instead of null?
| int readLength = length; | ||
| if (buffer.readableBytes() <= length) { | ||
| readLength = buffer.readableBytes(); | ||
| buffers.poll(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
buffers.remove()?
| @Override | ||
| public List<ByteBuffer> readByteBuffers(int length) { | ||
| checkReadable(length); | ||
| readableBytes -= length; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe better to decrement this within the loop so that the buffer state remains consistent in case of runtime exception?
Also how about a special case (should be common):
if (buffers.size() == 1) {
return (readableBytes == 0 ? buffers.poll() : buffers.peek()).readByteBuffers(length);
}…he responsibility of releasing resources after data access.
…release data when done.
|
Close in favor of #7330. |
TODO: tests and Javadoc enhancement.