Skip to main content

cranpose_core/slot/
table.rs

1use std::rc::Rc;
2
3use super::{
4    AnchorRegistry, DeferredDrop, GroupRecord, MovableIndex, NodeRecord, PayloadAnchorRegistry,
5    SlotLifecycleCoordinator, SlotWriteSessionState, debug::SlotTableDiagnostics,
6    growth::GrowthSlack, payload_store::PayloadStore,
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
34/// Storage for the groups, remembered values and nodes that one composition produced.
35pub struct SlotTable {
36    storage_id: SlotStorageIdentity,
37    pub(super) groups: Vec<GroupRecord>,
38    pub(super) payloads: PayloadStore,
39    pub(super) nodes: Vec<NodeRecord>,
40    pub(super) anchors: AnchorRegistry,
41    pub(super) payload_anchors: PayloadAnchorRegistry,
42    pub(super) movables: MovableIndex,
43    pub(super) diagnostics: SlotTableDiagnostics,
44    stale_group_indexes: metadata::StaleGroupIndexes,
45    next_group_generation: u32,
46}
47
48impl SlotTable {
49    /// Creates an empty table.
50    pub fn new() -> Self {
51        Self {
52            storage_id: SlotStorageIdentity::new(),
53            groups: Vec::new(),
54            payloads: PayloadStore::default(),
55            nodes: Vec::new(),
56            anchors: AnchorRegistry::new(),
57            payload_anchors: PayloadAnchorRegistry::new(),
58            movables: MovableIndex::default(),
59            diagnostics: SlotTableDiagnostics::default(),
60            stale_group_indexes: metadata::StaleGroupIndexes::default(),
61            next_group_generation: 1,
62        }
63    }
64
65    pub(crate) fn write_session<'a>(
66        &'a mut self,
67        lifecycle: &'a mut SlotLifecycleCoordinator,
68        state: &'a mut SlotWriteSessionState,
69    ) -> SlotWriteSession<'a> {
70        SlotWriteSession {
71            table: self,
72            lifecycle,
73            state,
74        }
75    }
76
77    pub(crate) fn storage_id(&self) -> usize {
78        self.storage_id.id()
79    }
80
81    #[cfg(test)]
82    pub(in crate::slot) fn set_next_group_generation_for_test(&mut self, generation: u32) {
83        self.next_group_generation = generation;
84    }
85
86    #[cfg(test)]
87    pub(in crate::slot) fn set_next_group_anchor_for_test(&mut self, next_anchor: usize) {
88        self.anchors.set_next_anchor_for_test(next_anchor);
89    }
90
91    #[cfg(test)]
92    pub(in crate::slot) fn set_next_payload_anchor_for_test(&mut self, next_anchor: usize) {
93        self.payload_anchors.set_next_id_for_test(next_anchor);
94    }
95
96    pub(crate) fn compact_storage(&mut self) {
97        self.groups.shrink_to_fit();
98        self.payloads.compact();
99        self.nodes.shrink_to_fit();
100        self.anchors.shrink_to_fit();
101        self.payload_anchors.shrink_to_fit();
102        self.movables.shrink_to_fit();
103    }
104
105    pub(crate) fn storage_capacity(&self) -> usize {
106        self.groups.capacity() + self.payloads.capacity() + self.nodes.capacity()
107    }
108
109    pub(crate) fn trim_growth_slack(&mut self) {
110        self.groups.trim_growth_slack();
111        self.payloads.trim_growth_slack();
112        self.nodes.trim_growth_slack();
113        self.anchors.trim_growth_slack();
114        self.payload_anchors.trim_growth_slack();
115    }
116
117    pub(crate) fn take_effect_drops(&mut self) -> Vec<DeferredDrop> {
118        let mut drops = Vec::new();
119        self.payloads.for_each_mut(|payload| {
120            if let Some(fresh) = payload.payload_type.fresh {
121                let old = std::mem::replace(&mut payload.value, fresh());
122                drops.push(DeferredDrop::payload(old));
123            }
124        });
125        drops
126    }
127
128    pub(crate) fn take_all_drops(&mut self) -> Vec<DeferredDrop> {
129        let mut drops = Vec::with_capacity(self.payloads.len());
130        self.payloads
131            .drain_rev(|payload| drops.push(payload.into_deferred_drop()));
132        self.groups.clear();
133        self.stale_group_indexes = metadata::StaleGroupIndexes::default();
134        self.nodes.clear();
135        self.anchors.clear();
136        self.payload_anchors.clear();
137        self.movables.clear();
138        drops
139    }
140}
141
142impl Default for SlotTable {
143    fn default() -> Self {
144        Self::new()
145    }
146}