metrale_storage/snapshot_swap/
mmap_arena.rs1use anyhow::{Result, bail};
11
12use super::SlotArena;
13
14pub struct MmapSlotArena {
18 base: *mut u8,
19 slot_bytes: usize,
20 num_slots: usize,
21}
22unsafe impl Send for MmapSlotArena {}
23
24impl MmapSlotArena {
25 pub unsafe fn new(base: *mut u8, slot_bytes: usize, num_slots: usize) -> Self {
31 Self {
32 base,
33 slot_bytes,
34 num_slots,
35 }
36 }
37 fn slot_ptr(&self, slot: usize) -> *mut u8 {
38 unsafe { self.base.add(slot * self.slot_bytes) }
40 }
41}
42
43impl SlotArena for MmapSlotArena {
44 fn slot_bytes(&self) -> usize {
45 self.slot_bytes
46 }
47 fn num_slots(&self) -> usize {
48 self.num_slots
49 }
50 fn read_slot(&self, slot: usize, out: &mut [u8]) -> Result<()> {
51 if slot >= self.num_slots || out.len() != self.slot_bytes {
52 bail!("read_slot({slot}) out of range / size mismatch");
53 }
54 unsafe {
55 std::ptr::copy_nonoverlapping(self.slot_ptr(slot), out.as_mut_ptr(), self.slot_bytes)
56 };
57 Ok(())
58 }
59 fn write_slot(&mut self, slot: usize, bytes: &[u8]) -> Result<()> {
60 if slot >= self.num_slots || bytes.len() != self.slot_bytes {
61 bail!("write_slot({slot}) out of range / size mismatch");
62 }
63 unsafe {
64 std::ptr::copy_nonoverlapping(bytes.as_ptr(), self.slot_ptr(slot), self.slot_bytes)
65 };
66 Ok(())
67 }
68}
69
70#[cfg(test)]
71#[path = "mmap_arena_tests.rs"]
72mod tests;