atomo/
batch.rs

1use std::ops::{Deref, DerefMut};
2
3use fxhash::FxHashMap;
4
5pub type BoxedVec = Box<[u8]>;
6
7pub type BatchHashMap = FxHashMap<BoxedVec, Operation>;
8
9/// A vertical batch contains a list of slots for each different table. Putting
10/// the [`VerticalBatch`] into a [`SnapshotList`] will provide a valid snapshot
11/// list.
12pub struct VerticalBatch(Vec<BatchHashMap>);
13
14/// The change on a value.
15pub enum Operation {
16    Remove,
17    Insert(BoxedVec),
18}
19
20impl VerticalBatch {
21    /// Returns a new empty vertical batch with the given size. The
22    /// size can be used for the number of tables.
23    #[inline(always)]
24    pub fn new(size: usize) -> Self {
25        let mut vec = Vec::with_capacity(size);
26        vec.resize_with(size, FxHashMap::default);
27        VerticalBatch(vec)
28    }
29
30    /// Consume the vertical batch and returns the underlying vector of batches.
31    #[inline(always)]
32    pub fn into_raw(self) -> Vec<BatchHashMap> {
33        self.0
34    }
35
36    #[inline(always)]
37    pub fn get(&self, index: usize) -> &BatchHashMap {
38        debug_assert!(index < self.0.len());
39        &self.0[index]
40    }
41
42    #[inline(always)]
43    pub fn get_mut(&mut self, index: usize) -> &mut BatchHashMap {
44        debug_assert!(index < self.0.len());
45        &mut self.0[index]
46    }
47
48    /// Return a reference to a single slot in the vertical batch.
49    ///
50    /// # Safety
51    ///
52    /// It is up to the caller to ensure:
53    ///
54    /// 1. The index is only claimed once.
55    /// 2. The reference's lifetime is bounded to this [`VerticalBatch`].
56    #[inline(always)]
57    pub unsafe fn claim(&self, index: usize) -> BatchReference {
58        let x = self.0.get_unchecked(index) as *const BatchHashMap as *mut BatchHashMap;
59        BatchReference(x)
60    }
61}
62
63/// The reference to a single batch slot.
64pub struct BatchReference(*mut BatchHashMap);
65
66impl BatchReference {
67    #[inline(always)]
68    pub fn as_mut(&mut self) -> &mut BatchHashMap {
69        unsafe { &mut *self.0 }
70    }
71}
72
73impl Deref for BatchReference {
74    type Target = BatchHashMap;
75
76    #[inline(always)]
77    fn deref(&self) -> &Self::Target {
78        unsafe { &*self.0 }
79    }
80}
81
82impl DerefMut for BatchReference {
83    #[inline(always)]
84    fn deref_mut(&mut self) -> &mut Self::Target {
85        unsafe { &mut *self.0 }
86    }
87}