cranpose_core/slot/
table.rs1use 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
34pub 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 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}