Skip to main content

trx_rs/
mmap_backing.rs

1use bytemuck::{cast_slice, cast_slice_mut, Pod};
2use memmap2::{Mmap, MmapMut};
3
4use crate::error::{Result, TrxError};
5
6/// Convert a `Vec<T: Pod>` into a `Vec<u8>` by copying the raw bytes.
7pub fn vec_to_bytes<T: Pod>(v: Vec<T>) -> Vec<u8> {
8    cast_slice::<T, u8>(&v).to_vec()
9}
10
11/// Owns the backing memory for a TRX data array.
12///
13/// May be a read-only mmap, a read-write mmap, or an owned heap buffer
14/// (used for converted offsets, deep copies, etc.).
15pub enum MmapBacking {
16    ReadOnly(Mmap),
17    ReadWrite(MmapMut),
18    Owned(Vec<u8>),
19}
20
21impl MmapBacking {
22    /// Raw bytes view.
23    pub fn as_bytes(&self) -> &[u8] {
24        match self {
25            MmapBacking::ReadOnly(m) => m,
26            MmapBacking::ReadWrite(m) => m,
27            MmapBacking::Owned(v) => v,
28        }
29    }
30
31    /// Mutable raw bytes view (only for ReadWrite and Owned).
32    pub fn as_bytes_mut(&mut self) -> Result<&mut [u8]> {
33        match self {
34            MmapBacking::ReadOnly(_) => Err(TrxError::Argument(
35                "cannot mutably access read-only mmap".into(),
36            )),
37            MmapBacking::ReadWrite(m) => Ok(m.as_mut()),
38            MmapBacking::Owned(v) => Ok(v.as_mut_slice()),
39        }
40    }
41
42    /// Length in bytes.
43    pub fn len(&self) -> usize {
44        self.as_bytes().len()
45    }
46
47    /// Whether the backing is empty.
48    pub fn is_empty(&self) -> bool {
49        self.len() == 0
50    }
51
52    pub fn is_mapped(&self) -> bool {
53        matches!(self, MmapBacking::ReadOnly(_) | MmapBacking::ReadWrite(_))
54    }
55
56    /// Cast the raw bytes to a typed slice.
57    ///
58    /// Panics if the bytes are not aligned or the length is not a multiple
59    /// of `size_of::<T>()`.
60    pub fn cast_slice<T: Pod>(&self) -> &[T] {
61        cast_slice(self.as_bytes())
62    }
63
64    /// Cast the raw bytes to a mutable typed slice.
65    pub fn cast_slice_mut<T: Pod>(&mut self) -> Result<&mut [T]> {
66        let bytes = self.as_bytes_mut()?;
67        Ok(cast_slice_mut(bytes))
68    }
69}
70
71impl std::fmt::Debug for MmapBacking {
72    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73        match self {
74            MmapBacking::ReadOnly(m) => write!(f, "ReadOnly({} bytes)", m.len()),
75            MmapBacking::ReadWrite(m) => write!(f, "ReadWrite({} bytes)", m.len()),
76            MmapBacking::Owned(v) => write!(f, "Owned({} bytes)", v.len()),
77        }
78    }
79}