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