Skip to content

Allow creating custom Bytes instances using constructor that takes an Arc<dyn Any> #571

@rklaehn

Description

@rklaehn

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 #526 and #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()); };

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions