Skip to main content

cranpose_core/slot/
table.rs

1use std::rc::Rc;
2
3use super::{
4    AnchorRegistry, DeferredDrop, GroupRecord, MovableIndex, NodeRecord, PayloadAnchorRegistry,
5    PayloadRecord, ScopeIndex, SlotLifecycleCoordinator, SlotWriteSessionState,
6    debug::SlotTableDiagnostics,
7};
8
9mod metadata;
10mod mutation;
11mod values;
12
13#[cfg(test)]
14pub(crate) use values::ValueSlotError;
15
16struct SlotStorageIdentity(Rc<()>);
17
18impl SlotStorageIdentity {
19    fn new() -> Self {
20        Self(Rc::new(()))
21    }
22
23    fn id(&self) -> usize {
24        Rc::as_ptr(&self.0).addr()
25    }
26}
27
28pub(crate) struct SlotWriteSession<'a> {
29    pub(super) table: &'a mut SlotTable,
30    pub(in crate::slot) lifecycle: &'a mut SlotLifecycleCoordinator,
31    pub(in crate::slot) state: &'a mut SlotWriteSessionState,
32}
33
34pub struct SlotTable {
35    storage_id: SlotStorageIdentity,
36    pub(super) groups: Vec<GroupRecord>,
37    pub(super) payloads: Vec<PayloadRecord>,
38    pub(super) nodes: Vec<NodeRecord>,
39    pub(super) anchors: AnchorRegistry,
40    pub(super) payload_anchors: PayloadAnchorRegistry,
41    pub(super) scope_index: ScopeIndex,
42    pub(super) movables: MovableIndex,
43    pub(super) diagnostics: SlotTableDiagnostics,
44    next_group_generation: u32,
45}
46
47impl SlotTable {
48    pub fn new() -> Self {
49        Self {
50            storage_id: SlotStorageIdentity::new(),
51            groups: Vec::new(),
52            payloads: Vec::new(),
53            nodes: Vec::new(),
54            anchors: AnchorRegistry::new(),
55            payload_anchors: PayloadAnchorRegistry::new(),
56            scope_index: ScopeIndex::new(),
57            movables: MovableIndex::default(),
58            diagnostics: SlotTableDiagnostics::default(),
59            next_group_generation: 1,
60        }
61    }
62
63    pub(crate) fn write_session<'a>(
64        &'a mut self,
65        lifecycle: &'a mut SlotLifecycleCoordinator,
66        state: &'a mut SlotWriteSessionState,
67    ) -> SlotWriteSession<'a> {
68        SlotWriteSession {
69            table: self,
70            lifecycle,
71            state,
72        }
73    }
74
75    pub(crate) fn storage_id(&self) -> usize {
76        self.storage_id.id()
77    }
78
79    #[cfg(test)]
80    pub(in crate::slot) fn set_next_group_generation_for_test(&mut self, generation: u32) {
81        self.next_group_generation = generation;
82    }
83
84    #[cfg(test)]
85    pub(in crate::slot) fn set_next_group_anchor_for_test(&mut self, next_anchor: usize) {
86        self.anchors.set_next_anchor_for_test(next_anchor);
87    }
88
89    #[cfg(test)]
90    pub(in crate::slot) fn set_next_payload_anchor_for_test(&mut self, next_anchor: usize) {
91        self.payload_anchors.set_next_id_for_test(next_anchor);
92    }
93
94    pub(crate) fn compact_storage(&mut self) {
95        self.groups.shrink_to_fit();
96        self.payloads.shrink_to_fit();
97        self.nodes.shrink_to_fit();
98        self.anchors.shrink_to_fit();
99        self.payload_anchors.shrink_to_fit();
100        self.scope_index.shrink_to_fit();
101        self.movables.shrink_to_fit();
102    }
103
104    pub(crate) fn take_effect_drops(&mut self) -> Vec<DeferredDrop> {
105        let mut drops = Vec::new();
106        for payload in self.payloads.iter_mut() {
107            let Some(fresh) = payload.fresh else {
108                continue;
109            };
110            let old = std::mem::replace(&mut payload.value, fresh());
111            drops.push(DeferredDrop::payload(old));
112        }
113        drops
114    }
115
116    pub(crate) fn take_all_drops(&mut self) -> Vec<DeferredDrop> {
117        let payload_count = self.payloads.len();
118        let mut drops = Vec::with_capacity(payload_count);
119        for payload in self.payloads.drain(..).rev() {
120            drops.push(payload.into_deferred_drop());
121        }
122        self.groups.clear();
123        self.nodes.clear();
124        self.anchors.clear();
125        self.payload_anchors.clear();
126        self.scope_index.clear();
127        self.movables.clear();
128        drops
129    }
130}
131
132impl Default for SlotTable {
133    fn default() -> Self {
134        Self::new()
135    }
136}