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