1use crate::{
4 chunked_slot_storage::ChunkedSlotStorage,
5 hierarchical_slot_storage::HierarchicalSlotStorage,
6 slot_storage::{GroupId, SlotStorage, StartGroup, ValueSlotId},
7 split_slot_storage::SplitSlotStorage,
8 Key, NodeId, Owned, ScopeId, SlotTable,
9};
10
11pub fn make_backend(kind: SlotBackendKind) -> SlotBackend {
15 SlotBackend::new(kind)
16}
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
20pub enum SlotBackendKind {
21 #[default]
23 Baseline,
24 Chunked,
26 Hierarchical,
28 Split,
30}
31
32pub enum SlotBackend {
34 Baseline(SlotTable),
35 Chunked(ChunkedSlotStorage),
36 Hierarchical(HierarchicalSlotStorage),
37 Split(SplitSlotStorage),
38}
39
40impl SlotBackend {
41 pub fn new(kind: SlotBackendKind) -> Self {
48 match kind {
49 SlotBackendKind::Baseline => Self::Baseline(SlotTable::new()),
50 SlotBackendKind::Chunked => Self::Chunked(ChunkedSlotStorage::new()),
51 SlotBackendKind::Hierarchical => Self::Hierarchical(HierarchicalSlotStorage::new()),
52 SlotBackendKind::Split => Self::Split(SplitSlotStorage::new()),
53 }
54 }
55}
56
57impl Default for SlotBackend {
58 fn default() -> Self {
59 Self::new(SlotBackendKind::default())
60 }
61}
62
63impl SlotStorage for SlotBackend {
65 type Group = GroupId;
66 type ValueSlot = ValueSlotId;
67
68 fn begin_group(&mut self, key: Key) -> StartGroup<Self::Group> {
69 match self {
70 Self::Baseline(s) => SlotStorage::begin_group(s, key),
71 Self::Chunked(s) => SlotStorage::begin_group(s, key),
72 Self::Hierarchical(s) => SlotStorage::begin_group(s, key),
73 Self::Split(s) => SlotStorage::begin_group(s, key),
74 }
75 }
76
77 fn set_group_scope(&mut self, group: Self::Group, scope: ScopeId) {
78 match self {
79 Self::Baseline(s) => SlotStorage::set_group_scope(s, group, scope),
80 Self::Chunked(s) => SlotStorage::set_group_scope(s, group, scope),
81 Self::Hierarchical(s) => SlotStorage::set_group_scope(s, group, scope),
82 Self::Split(s) => SlotStorage::set_group_scope(s, group, scope),
83 }
84 }
85
86 fn end_group(&mut self) {
87 match self {
88 Self::Baseline(s) => s.end_group(),
89 Self::Chunked(s) => s.end_group(),
90 Self::Hierarchical(s) => s.end_group(),
91 Self::Split(s) => s.end_group(),
92 }
93 }
94
95 fn skip_current_group(&mut self) {
96 match self {
97 Self::Baseline(s) => s.skip_current_group(),
98 Self::Chunked(s) => s.skip_current_group(),
99 Self::Hierarchical(s) => s.skip_current_group(),
100 Self::Split(s) => s.skip_current_group(),
101 }
102 }
103
104 fn nodes_in_current_group(&self) -> Vec<NodeId> {
105 match self {
106 Self::Baseline(s) => s.nodes_in_current_group(),
107 Self::Chunked(s) => s.nodes_in_current_group(),
108 Self::Hierarchical(s) => s.nodes_in_current_group(),
109 Self::Split(s) => s.nodes_in_current_group(),
110 }
111 }
112
113 fn begin_recranpose_at_scope(&mut self, scope: ScopeId) -> Option<Self::Group> {
114 match self {
115 Self::Baseline(s) => s.begin_recranpose_at_scope(scope),
116 Self::Chunked(s) => s.begin_recranpose_at_scope(scope),
117 Self::Hierarchical(s) => s.begin_recranpose_at_scope(scope),
118 Self::Split(s) => s.begin_recranpose_at_scope(scope),
119 }
120 }
121
122 fn end_recompose(&mut self) {
123 match self {
124 Self::Baseline(s) => s.end_recompose(),
125 Self::Chunked(s) => s.end_recompose(),
126 Self::Hierarchical(s) => s.end_recompose(),
127 Self::Split(s) => s.end_recompose(),
128 }
129 }
130
131 fn alloc_value_slot<T: 'static>(&mut self, init: impl FnOnce() -> T) -> Self::ValueSlot {
132 match self {
133 Self::Baseline(s) => s.alloc_value_slot(init),
134 Self::Chunked(s) => s.alloc_value_slot(init),
135 Self::Hierarchical(s) => s.alloc_value_slot(init),
136 Self::Split(s) => s.alloc_value_slot(init),
137 }
138 }
139
140 fn read_value<T: 'static>(&self, slot: Self::ValueSlot) -> &T {
141 match self {
142 Self::Baseline(s) => SlotStorage::read_value(s, slot),
143 Self::Chunked(s) => SlotStorage::read_value(s, slot),
144 Self::Hierarchical(s) => SlotStorage::read_value(s, slot),
145 Self::Split(s) => SlotStorage::read_value(s, slot),
146 }
147 }
148
149 fn read_value_mut<T: 'static>(&mut self, slot: Self::ValueSlot) -> &mut T {
150 match self {
151 Self::Baseline(s) => SlotStorage::read_value_mut(s, slot),
152 Self::Chunked(s) => SlotStorage::read_value_mut(s, slot),
153 Self::Hierarchical(s) => SlotStorage::read_value_mut(s, slot),
154 Self::Split(s) => SlotStorage::read_value_mut(s, slot),
155 }
156 }
157
158 fn write_value<T: 'static>(&mut self, slot: Self::ValueSlot, value: T) {
159 match self {
160 Self::Baseline(s) => SlotStorage::write_value(s, slot, value),
161 Self::Chunked(s) => SlotStorage::write_value(s, slot, value),
162 Self::Hierarchical(s) => SlotStorage::write_value(s, slot, value),
163 Self::Split(s) => SlotStorage::write_value(s, slot, value),
164 }
165 }
166
167 fn remember<T: 'static>(&mut self, init: impl FnOnce() -> T) -> Owned<T> {
168 match self {
169 Self::Baseline(s) => s.remember(init),
170 Self::Chunked(s) => s.remember(init),
171 Self::Hierarchical(s) => s.remember(init),
172 Self::Split(s) => s.remember(init),
173 }
174 }
175
176 fn peek_node(&self) -> Option<NodeId> {
177 match self {
178 Self::Baseline(s) => s.peek_node(),
179 Self::Chunked(s) => s.peek_node(),
180 Self::Hierarchical(s) => s.peek_node(),
181 Self::Split(s) => s.peek_node(),
182 }
183 }
184
185 fn record_node(&mut self, id: NodeId) {
186 match self {
187 Self::Baseline(s) => s.record_node(id),
188 Self::Chunked(s) => s.record_node(id),
189 Self::Hierarchical(s) => s.record_node(id),
190 Self::Split(s) => s.record_node(id),
191 }
192 }
193
194 fn advance_after_node_read(&mut self) {
195 match self {
196 Self::Baseline(s) => s.advance_after_node_read(),
197 Self::Chunked(s) => s.advance_after_node_read(),
198 Self::Hierarchical(s) => s.advance_after_node_read(),
199 Self::Split(s) => s.advance_after_node_read(),
200 }
201 }
202
203 fn step_back(&mut self) {
204 match self {
205 Self::Baseline(s) => s.step_back(),
206 Self::Chunked(s) => s.step_back(),
207 Self::Hierarchical(s) => s.step_back(),
208 Self::Split(s) => s.step_back(),
209 }
210 }
211
212 fn finalize_current_group(&mut self) -> bool {
213 match self {
214 Self::Baseline(s) => s.finalize_current_group(),
215 Self::Chunked(s) => s.finalize_current_group(),
216 Self::Hierarchical(s) => s.finalize_current_group(),
217 Self::Split(s) => s.finalize_current_group(),
218 }
219 }
220
221 fn reset(&mut self) {
222 match self {
223 Self::Baseline(s) => s.reset(),
224 Self::Chunked(s) => s.reset(),
225 Self::Hierarchical(s) => s.reset(),
226 Self::Split(s) => s.reset(),
227 }
228 }
229
230 fn flush(&mut self) {
231 match self {
232 Self::Baseline(s) => s.flush(),
233 Self::Chunked(s) => s.flush(),
234 Self::Hierarchical(s) => s.flush(),
235 Self::Split(s) => s.flush(),
236 }
237 }
238}
239
240impl SlotBackend {
242 pub fn debug_dump_groups(&self) -> Vec<(usize, Key, Option<ScopeId>, usize)> {
243 match self {
244 Self::Baseline(s) => s.debug_dump_groups(),
245 Self::Hierarchical(s) => s.debug_dump_groups(),
246 Self::Chunked(s) => s.debug_dump_groups(),
247 Self::Split(s) => s.debug_dump_groups(),
248 }
249 }
250
251 pub fn debug_dump_all_slots(&self) -> Vec<(usize, String)> {
252 match self {
253 Self::Baseline(s) => s.debug_dump_all_slots(),
254 Self::Hierarchical(s) => s.debug_dump_all_slots(),
255 Self::Chunked(s) => s.debug_dump_all_slots(),
256 Self::Split(s) => s.debug_dump_all_slots(),
257 }
258 }
259}