You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, bytes_vectored takes a slice of initialized IoSliceMut. This has two drawbacks:
If one wants to be pretty sure that the slice will have sufficient length, he may want to allocate e.g. 128 items-long array on stack and pass it in, however, he needs to initialize each item, causing slow down.
bytes_vectored is tied to specific implementation of vectored slice from std this makes it clunky to work in no_std (one has to conditionally implement the method) and could miss potential opportunities. If there's any no_std library that would like to use vectored API, it's impossible to do. If there's some exotic platform that needs different io slices for different calls, only one can be optimized. (Unlikely, but still...)
The way to solve both problems is to pass in some kind of trait that can take normal Rust slice and convert it internally into whatever is needed. There are different options of how to do that:
FnMut with MaybeUninitSlice<u8>: fn bytes_vectored<'a, F: FnMut(&'a mut MaybeUninitSlice<u8>)>(&'a mut self, pusher: F); - this seems the most simple to me
A custom trait instead of FnMut with fn push_init(&mut self, data: &mut [u8]) and fn push_uninit(&mut [MaybeUninit<u8>])
Of course, this brings the question what about dyn traits. I'm not really sure how often dyn is used in this context. One possibility is to provide fn bytes_vectored_dyn too. Another would be to provide some helper bridging trait for that, but that's becoming complicated.
Another possibility would be to make BufMut trait generic over io slice item type, requiring implementation of From<&mut [u8]> and From<&mut [MaybeUninit<u8>]> and ideally also From<&mut MaybeUninitSlice<u8>>, but until we have HRTB for types in Rust, it might be less useful.
I gave examples on BytesMut trait, which is more complicated, but the same goes for Bytes trait.
The text was updated successfully, but these errors were encountered:
I just realized my proposal also solves the problem raised in tokio-rs/tokio#1744 (comment) regarding many small slices passed to something that doesn't support vectored IO. If the writer doesn't support vectored IO, it can simply pass a closure that copies the data between staging buffer and the slices instead.
Currently,
bytes_vectored
takes a slice of initializedIoSliceMut
. This has two drawbacks:bytes_vectored
is tied to specific implementation of vectored slice fromstd
this makes it clunky to work inno_std
(one has to conditionally implement the method) and could miss potential opportunities. If there's anyno_std
library that would like to use vectored API, it's impossible to do. If there's some exotic platform that needs different io slices for different calls, only one can be optimized. (Unlikely, but still...)The way to solve both problems is to pass in some kind of trait that can take normal Rust slice and convert it internally into whatever is needed. There are different options of how to do that:
FnMut
:fn bytes_vectored<'a, F: FnMut(&'a mut [MaybeUninit<u8>])>(&'a mut self, pusher: F);
FnMut
withMaybeUninitSlice<u8>
:fn bytes_vectored<'a, F: FnMut(&'a mut MaybeUninitSlice<u8>)>(&'a mut self, pusher: F);
- this seems the most simple to meFnMut
withfn push_init(&mut self, data: &mut [u8])
andfn push_uninit(&mut [MaybeUninit<u8>])
Of course, this brings the question what about
dyn
traits. I'm not really sure how oftendyn
is used in this context. One possibility is to providefn bytes_vectored_dyn
too. Another would be to provide some helper bridging trait for that, but that's becoming complicated.Alternatively, it could be decided that conversion to native slice is not needed and use something like
possibly_uninit::slice::Cursor<IoSliceMut>
.Another possibility would be to make
BufMut
trait generic over io slice item type, requiring implementation ofFrom<&mut [u8]>
andFrom<&mut [MaybeUninit<u8>]>
and ideally alsoFrom<&mut MaybeUninitSlice<u8>>
, but until we have HRTB for types in Rust, it might be less useful.I gave examples on
BytesMut
trait, which is more complicated, but the same goes forBytes
trait.The text was updated successfully, but these errors were encountered: