brk_vec/enums/
values.rs

1use std::ops::Range;
2
3use memmap2::Mmap;
4use zerocopy::{Immutable, IntoBytes, KnownLayout, TryFromBytes};
5
6use crate::MAX_PAGE_SIZE;
7
8use super::Result;
9
10#[derive(Debug)]
11pub enum Values<T> {
12    Owned(Box<[T]>),
13    Ref(Box<Mmap>),
14}
15
16impl<T> Values<T> {
17    const PER_PAGE: usize = MAX_PAGE_SIZE / Self::SIZE_OF_T;
18    const SIZE_OF_T: usize = size_of::<T>();
19
20    pub fn get(&self, index: usize) -> Result<Option<&T>>
21    where
22        T: TryFromBytes + IntoBytes + Immutable + KnownLayout,
23    {
24        let index = Self::index_to_decoded_index(index);
25
26        Ok(match self {
27            Self::Owned(a) => a.get(index),
28            Self::Ref(m) => {
29                let range = Self::index_to_byte_range(index);
30                let source = &m[range];
31                Some(T::try_ref_from_bytes(source)?)
32            }
33        })
34    }
35
36    pub fn as_arr(&self) -> &[T] {
37        match self {
38            Self::Owned(a) => a,
39            Self::Ref(_) => unreachable!(),
40        }
41    }
42
43    pub fn as_mmap(&self) -> &Mmap {
44        match self {
45            Self::Owned(_) => unreachable!(),
46            Self::Ref(m) => m,
47        }
48    }
49
50    #[inline]
51    fn index_to_byte_range(index: usize) -> Range<usize> {
52        let index = Self::index_to_byte_index(index) as usize;
53        index..(index + Self::SIZE_OF_T)
54    }
55
56    #[inline]
57    fn index_to_byte_index(index: usize) -> u64 {
58        (index * Self::SIZE_OF_T) as u64
59    }
60
61    #[inline(always)]
62    fn index_to_decoded_index(index: usize) -> usize {
63        index % Self::PER_PAGE
64    }
65}
66
67impl<T> From<Box<[T]>> for Values<T> {
68    fn from(value: Box<[T]>) -> Self {
69        Self::Owned(value)
70    }
71}
72
73impl<T> From<Mmap> for Values<T> {
74    fn from(value: Mmap) -> Self {
75        Self::Ref(Box::new(value))
76    }
77}
78
79impl<T> Default for Values<T> {
80    fn default() -> Self {
81        Self::Owned(vec![].into_boxed_slice())
82    }
83}