mmaping a file yields a Mmap value. This value encapsulates a pointer into virtual memory, the length of that mapped data, and operations for flushing changes to disk. The value also implements deref to &[u8] which is what I really want to leverage.
I want the WhisperFile to own the Mmap so I can flush. But I want to split out ownership of the mmap data to slices held by Archive. I know the slices are non-overlapping, so maybe something like split_at_mut would be useful? The problem is that I can't get the slice deref to live long enough (which makes sense). Should I be using runtime reference counting to make sure slices are attached to their mmap? If so, are there any examples of this long-lived slice that people can point me to?
If you're just splitting the file up (and thus wouldn't waste too much memory this way), another possibility would be modifying the mmap library to allow (a) mapping directly from a File rather than always opening a path, and (b) mapping part of a file rather than the whole thing, neither of which should be a problem with the relevant underlying OS calls.
I'm not sure I could just mmap parts of the file. Reading over some documentation for mmap (beej's guide on mmap) it looks like:
void *mmap(void *addr, size_t len, int prot,
int flags, int fildes, off_t off);
where off_t off must be a multiple of page size (usually 4k). I could be dealing with multiple Archives inside of one page. It really depends on the layout of the WhisperFile which can vary wildly. Fine-grain borrowing from the one mmap memory region may be a requirement.
Edit: another issue is how to store the slice &[u8] which has the offsets in to the mmap? Even if I use an Rc<Mmap> in the Archive it won't have the offset and length of the slice available. Will I need to create my own deref impl for tracking those values and hiding them behind the scenes?
&archive[..] should yield the same byte slice as &mmap[ archive_start .. archive_end].
Given this limitation on page offsets (and even then, it would be expensive to make the mmap syscall repeatedly). I thought I could do some lifetime annotation magic but Rust can't track the data like I thought. Rc with a reimplementation of the Archive deref to &[u8] will work.