I am trying to implement deserialization into Rc<[u8]> without double allocating. The solutions I saw always creates an intermediate Vec<u8> and filling it in, and then converting it to an Rc. But this causes double allocation, first when filling in the Vec<u8>, and second converting it into Rc<[u8]>.
Is there a way to directly allocate N bytes (N is read from the deserialization reader) into Rc<[u8]>, and using the buffer as input to the reader? I am OK to unsafe usage as long as there are no memory leaks.
This can be accomplished in safe code, by using Rc::from_iter with a TrustedLen iterator:
Iterators of known length
When your
IteratorimplementsTrustedLenand is of an exact size, a single allocation will be made for theRc<[T]>. For example:
use std::rc::Rc;
pub fn rc_slice<T: Default>(n: usize) -> Rc<[T]> {
Rc::from_iter((0..n).map(|_| T::default()))
}
fn main() {
let mut data = rc_slice::<u8>(16);
// TODO: ovewrite contents of `data` with deserialized data
*Rc::get_mut(&mut data).unwrap()[0] = ...;
}
Note: This solution relies on a zero/Default initialization of the Rc contents prior to deserialization, which works for u8. If this isn't available for your type, consider using unsafe to allocate an uninitialized Rc-slice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With