Skip to content
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

Consider an unsplit method for Bytes #503

Open
eloff opened this issue Jul 5, 2021 · 2 comments · May be fixed by #538
Open

Consider an unsplit method for Bytes #503

eloff opened this issue Jul 5, 2021 · 2 comments · May be fixed by #538

Comments

@eloff
Copy link

eloff commented Jul 5, 2021

I was looking for a way to join two contiguous Bytes into one, but there isn't such a thing.

It's common in parsing code to read multiple logical messages into a single BytesMut, split them off into individual Bytes for processing, but then it if they need to be written somewhere it can be advantageous to recombine them, if possible, so there are fewer syscalls to write. It's also possible to just use writev, but that typically involves an allocation for the iovec array and not all platforms support writev, and it's not an option if you're using a TLS wrapper around the stream. Using writev also requires much more code.

I think it is possible to do this safely:

impl Bytes {
    pub fn unsplit(self, other: Self) -> (Option<Self>, Option<Self>) {
        if is_contiguous(&self, &other) {
            return Some(merge(self, other)), None
        }
       (Some(self), Some(other))
    }
}

Does this seem like a worthwhile addition to the library?

@eloff
Copy link
Author

eloff commented Aug 2, 2021

I needed this in more than one place as it turns out, so I implemented it using unsafe. Feel free to use any of this code in the bytes library, and relicense as required.

https://gist.github.com/eloff/6e0c236ae6388744a7d5b76a5e0e9b6c

adeschamps added a commit to adeschamps/bytes that referenced this issue Mar 25, 2022
This is based largely on the example of `BytesMut::unsplit`. If two
`Bytes` are contiguous and point to the same allocation, then they are
cheaply merged. Otherwise, a new `BytesMut` is allocated, copies data
from `self` and `other`, and `self` is replaced with `new.freeze()`.

Closes tokio-rs#503
@adeschamps adeschamps linked a pull request Mar 25, 2022 that will close this issue
@xonatius
Copy link

Looks like duplicate of #287

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 a pull request may close this issue.

2 participants