Skip to content

Conversation

@camshaft
Copy link
Contributor

@camshaft camshaft commented Nov 27, 2023

Description of changes:

The current ReceiveBuffer implementation requires copying all stream data into BytesMut buffers to ensure stream data is correctly ordered. This ends up requiring an allocation and a copy, even in scenarios where the stream data being received is at the current offset, and could potentially be copied into an application-provided buffer.

This change adds support for that usecase by adding a skip(len: usize) method that allows a caller to increment the current offset by len and bypass copying the data into the buffer itself.

Testing:

I added a Skip operation to the fuzz tests, along with a data checker to ensure the data being written to the buffer is the same that is being read. I also updated the committed corpus to include the new input coverage.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@camshaft camshaft force-pushed the camshaft/receive-buffer-skip branch from d2db75e to 5152775 Compare November 27, 2023 23:47
@camshaft camshaft force-pushed the camshaft/receive-buffer-skip branch from 5152775 to def10e4 Compare November 27, 2023 23:53
@camshaft camshaft marked this pull request as ready for review November 28, 2023 00:10
pub fn skip(&mut self, len: u64) {
// trim off the data buffer
unsafe {
let len = len.min(usize::MAX as u64) as usize;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why take a u64 for len instead of usize?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The caller is using a u64 and would have to convert to usize anyway. The len should never be bigger that 64k so it probably doesn't matter either way. But I can change it to a usize if you think that's clearer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw the add_start above using usize so I was currious, but as you said it doesn't really matter. If it should never be bigger than 64k should we put a debug_assert! or do something like let len:usize = len.try_into().expect("len must be <= 64")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try adding an assertion and see if my assumption is true 😁

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

turns out it wasn't when writing a FIN segment. I've fixed that and added a test for it as well.

Comment on lines 301 to 303
if len == 0 {
return Ok(());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this an appropriate use of ensure!, or should it just be for error cases?

Suggested change
if len == 0 {
return Ok(());
}
ensure!(len > 0, Ok(()));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Funny you mention it.. I went back and forth on using it for this. Didn't know if it would be confusing to return Ok or not. What are your thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its not really confusing (especially with the comment there), but without the return keyword sticking out it takes a couple more cycles to comprehend if you're not used to ensure. But maybe the answer is just to get used to it :-)

@camshaft camshaft merged commit 3b68189 into main Nov 29, 2023
@camshaft camshaft deleted the camshaft/receive-buffer-skip branch November 29, 2023 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants