bytes
bytes copied to clipboard
Allow creating custom Bytes instances using constructor that takes an Arc<dyn Any>
I have a situation where I have a memory mapped file and want to pass a slice of it around unencumbered by lifetimes, but without copying. I have looked into the Bytes crate, but could not use it since there is no way to create a custom Bytes instance.
See https://github.com/tokio-rs/bytes/issues/526 and https://github.com/tokio-rs/bytes/issues/437 .
I ended up writing my own bytes like struct that is a byte slice and an Arc<dyn Any>
. See Blob .
This works very similar to Bytes, except that the reference counting is done by the Arc<dyn Any>
instead of a custom VTable. There is a Constructor where you pass in a slice and an Arc<dyn Any>
and promise that the slice will be valid as long as whatever the Arc<dyn Any>
points to is kept alive.
You could easily implement a custom VTable for this approach and expose a similar method in the Bytes crate. I think it is a pretty minimal way to allow for custom Bytes instances without having to expose internals like the VTable.
I guess you would have to do the same for Rc for completeness sake, but still it is much less surface area than approaches that require to make the VTable
public, and also quite convenient for the user.
Here is how it is used:
use memmap::MmapOptions;
use std::{io::Write, sync::Arc};
// create a large file
let mut large_file = tempfile().unwrap();
large_file.write_all(&[0u8; 1024 * 1024])?;
// map it and wrap the MMap in an arc
let mmap = Arc::new(unsafe { MmapOptions::new().map(&large_file).unwrap() });
// create a bytes that points to a part of the large file, without allocation
// the Bytes instance keeps the mmap alive as long as needed
let slice = unsafe { Bytes::custom_new(&mmap[10..10000], mmap.clone()); };
Note: I am not saying that this is the best way forward. Any of the other two ( #526 and #437 ) would also do.
It would just be great if there was any way to create a Bytes for something like a memory mapped buffer without copying.
Closing as duplicate of #437.