1#![allow(clippy::collapsible_match)]
11
12use crate::{
13 slot_storage::{GroupId, SlotStorage, StartGroup, ValueSlotId},
14 AnchorId, Key, NodeId, Owned, ScopeId,
15};
16use std::any::Any;
17use std::cell::Cell;
18
19#[derive(Default)]
20pub struct SlotTable {
21 slots: Vec<Slot>, cursor: usize,
23 group_stack: Vec<GroupFrame>, anchors: Vec<usize>, anchors_dirty: bool,
28 next_anchor_id: Cell<usize>,
30 last_start_was_gap: bool,
32}
33
34enum Slot {
35 Group {
36 key: Key,
37 anchor: AnchorId,
38 len: usize,
39 scope: Option<ScopeId>,
40 has_gap_children: bool,
41 },
42 Value {
43 anchor: AnchorId,
44 data: Box<dyn Any>,
45 },
46 Node {
47 anchor: AnchorId,
48 id: NodeId,
49 },
50 Gap {
55 anchor: AnchorId,
56 group_key: Option<Key>,
58 group_scope: Option<ScopeId>,
60 group_len: usize,
62 },
63}
64
65struct GroupFrame {
66 key: Key,
67 start: usize, end: usize, force_children_recompose: bool,
70}
71
72const INVALID_ANCHOR_POS: usize = usize::MAX;
73
74#[derive(Debug, PartialEq)]
75enum SlotKind {
76 Group,
77 Value,
78 Node,
79 Gap,
80}
81
82impl Slot {
83 fn kind(&self) -> SlotKind {
84 match self {
85 Slot::Group { .. } => SlotKind::Group,
86 Slot::Value { .. } => SlotKind::Value,
87 Slot::Node { .. } => SlotKind::Node,
88 Slot::Gap { .. } => SlotKind::Gap,
89 }
90 }
91
92 fn anchor_id(&self) -> AnchorId {
94 match self {
95 Slot::Group { anchor, .. } => *anchor,
96 Slot::Value { anchor, .. } => *anchor,
97 Slot::Node { anchor, .. } => *anchor,
98 Slot::Gap { anchor, .. } => *anchor,
99 }
100 }
101
102 fn as_value<T: 'static>(&self) -> &T {
103 match self {
104 Slot::Value { data, .. } => data.downcast_ref::<T>().expect("slot value type mismatch"),
105 _ => panic!("slot is not a value"),
106 }
107 }
108
109 fn as_value_mut<T: 'static>(&mut self) -> &mut T {
110 match self {
111 Slot::Value { data, .. } => data.downcast_mut::<T>().expect("slot value type mismatch"),
112 _ => panic!("slot is not a value"),
113 }
114 }
115}
116
117impl Default for Slot {
118 fn default() -> Self {
119 Slot::Group {
120 key: 0,
121 anchor: AnchorId::INVALID,
122 len: 0,
123 scope: None,
124 has_gap_children: false,
125 }
126 }
127}
128
129impl SlotTable {
130 const INITIAL_CAP: usize = 32;
131 const LOCAL_GAP_SCAN: usize = 256; pub fn new() -> Self {
134 Self {
135 slots: Vec::new(),
136 cursor: 0,
137 group_stack: Vec::new(),
138 anchors: Vec::new(),
139 anchors_dirty: false,
140 next_anchor_id: Cell::new(1), last_start_was_gap: false,
142 }
143 }
144
145 pub fn current_group(&self) -> usize {
146 self.group_stack.last().map(|f| f.start).unwrap_or(0)
147 }
148
149 pub fn group_key(&self, index: usize) -> Option<Key> {
150 match self.slots.get(index) {
151 Some(Slot::Group { key, .. }) => Some(*key),
152 Some(Slot::Gap { group_key, .. }) => *group_key,
153 _ => None,
154 }
155 }
156
157 fn ensure_capacity(&mut self) {
158 if self.slots.is_empty() {
159 self.slots.reserve(Self::INITIAL_CAP);
160 self.append_gap_slots(Self::INITIAL_CAP);
161 } else if self.cursor == self.slots.len() {
162 self.grow_slots();
163 }
164 }
165
166 fn force_gap_here(&mut self, cursor: usize) {
167 self.slots[cursor] = Slot::Gap {
170 anchor: AnchorId::INVALID,
171 group_key: None,
172 group_scope: None,
173 group_len: 0,
174 };
175 }
176
177 fn find_right_gap_run(&self, from: usize, scan_limit: usize) -> Option<(usize, usize)> {
178 let end = (from + scan_limit).min(self.slots.len());
179 let mut i = from;
180 while i < end {
181 if let Some(Slot::Gap { anchor, .. }) = self.slots.get(i) {
182 if *anchor == AnchorId::INVALID {
183 let start = i;
184 let mut len = 1;
185 while i + len < end {
186 match self.slots.get(i + len) {
187 Some(Slot::Gap { anchor, .. }) if *anchor == AnchorId::INVALID => {
188 len += 1;
189 }
190 _ => break,
191 }
192 }
193 return Some((start, len));
194 }
195 }
196 i += 1;
197 }
198 None
199 }
200
201 fn ensure_gap_at_local(&mut self, cursor: usize) {
202 if matches!(self.slots.get(cursor), Some(Slot::Gap { .. })) {
203 return;
204 }
205 self.ensure_capacity();
206
207 if let Some((run_start, run_len)) = self.find_right_gap_run(cursor, Self::LOCAL_GAP_SCAN) {
208 self.shift_group_frames(cursor, run_len as isize);
209 self.shift_anchor_positions_from(cursor, run_len as isize);
210 self.slots[cursor..run_start + run_len].rotate_right(run_len);
211 return;
212 }
213
214 self.force_gap_here(cursor);
215 }
216
217 fn append_gap_slots(&mut self, count: usize) {
218 if count == 0 {
219 return;
220 }
221 for _ in 0..count {
222 self.slots.push(Slot::Gap {
223 anchor: AnchorId::INVALID,
224 group_key: None,
225 group_scope: None,
226 group_len: 0,
227 });
228 }
229 }
230
231 fn grow_slots(&mut self) {
232 let old_len = self.slots.len();
233 let target_len = (old_len.saturating_mul(2)).max(Self::INITIAL_CAP);
234 let additional = target_len.saturating_sub(old_len);
235 if additional == 0 {
236 return;
237 }
238 self.slots.reserve(additional);
239 self.append_gap_slots(additional);
240 }
241
242 fn allocate_anchor(&self) -> AnchorId {
244 let id = self.next_anchor_id.get();
245 self.next_anchor_id.set(id + 1);
246 AnchorId(id)
247 }
248
249 fn register_anchor(&mut self, anchor: AnchorId, position: usize) {
251 debug_assert!(anchor.is_valid(), "attempted to register invalid anchor");
252 let idx = anchor.0;
253 if idx == 0 {
254 return;
255 }
256 if idx >= self.anchors.len() {
257 self.anchors.resize(idx + 1, INVALID_ANCHOR_POS);
258 }
259 self.anchors[idx] = position;
260 }
261
262 fn take_last_start_was_gap(&mut self) -> bool {
265 let was_gap = self.last_start_was_gap;
266 self.last_start_was_gap = false;
267 was_gap
268 }
269
270 fn find_group_owner_index(&self, start: usize) -> Option<usize> {
271 if start == 0 || self.slots.is_empty() {
272 return None;
273 }
274
275 let mut idx = start.saturating_sub(1);
276 loop {
277 if let Some(Slot::Group { len, .. }) = self.slots.get(idx) {
278 let extent_end = idx.saturating_add(*len);
279 if start < extent_end {
280 return Some(idx);
281 }
282 }
283 if idx == 0 {
284 break;
285 }
286 idx -= 1;
287 }
288 None
289 }
290
291 fn resolve_anchor(&self, anchor: AnchorId) -> Option<usize> {
293 let idx = anchor.0;
294 if idx == 0 {
295 return None;
296 }
297 self.anchors
298 .get(idx)
299 .copied()
300 .filter(|&pos| pos != INVALID_ANCHOR_POS)
301 }
302
303 pub fn mark_range_as_gaps(
307 &mut self,
308 start: usize,
309 end: usize,
310 owner_index: Option<usize>,
311 ) -> bool {
312 let mut i = start;
313 let end = end.min(self.slots.len());
314 let mut marked_any = false;
315
316 while i < end {
317 if i >= self.slots.len() {
318 break;
319 }
320
321 let (anchor, group_len, group_key, group_scope) = {
322 let slot = &self.slots[i];
323 let anchor = slot.anchor_id();
324 let (group_len, group_key, group_scope) = match slot {
325 Slot::Group {
326 len, key, scope, ..
327 } => (*len, Some(*key), *scope),
328 Slot::Gap {
332 group_len,
333 group_key,
334 group_scope,
335 ..
336 } => (*group_len, *group_key, *group_scope),
337 _ => (0, None, None),
338 };
339 (anchor, group_len, group_key, group_scope)
340 };
341
342 self.slots[i] = Slot::Gap {
345 anchor,
346 group_key,
347 group_scope,
348 group_len,
349 };
350 marked_any = true;
351
352 if group_len > 0 {
354 let children_end = (i + group_len).min(end);
356 for j in (i + 1)..children_end {
357 if j < self.slots.len() {
358 if let Slot::Group {
360 key: nested_key,
361 scope: nested_scope,
362 len: nested_len,
363 ..
364 } = self.slots[j]
365 {
366 let child_anchor = self.slots[j].anchor_id();
367 self.slots[j] = Slot::Gap {
368 anchor: child_anchor,
369 group_key: Some(nested_key),
370 group_scope: nested_scope,
371 group_len: nested_len,
372 };
373 marked_any = true;
374 } else {
375 let child_anchor = self.slots[j].anchor_id();
377 self.slots[j] = Slot::Gap {
378 anchor: child_anchor,
379 group_key: None,
380 group_scope: None,
381 group_len: 0,
382 };
383 marked_any = true;
384 }
385 }
386 }
387 i = (i + group_len).max(i + 1);
388 } else {
389 i += 1;
390 }
391 }
392
393 if marked_any {
394 let owner_idx = owner_index.or_else(|| self.find_group_owner_index(start));
395 if let Some(idx) = owner_idx {
396 if let Some(Slot::Group {
397 has_gap_children, ..
398 }) = self.slots.get_mut(idx)
399 {
400 *has_gap_children = true;
401 }
402 if let Some(frame) = self.group_stack.iter_mut().find(|frame| frame.start == idx) {
403 frame.force_children_recompose = true;
404 }
405 }
406 }
407 marked_any
408 }
409
410 pub fn get_group_scope(&self, index: usize) -> Option<ScopeId> {
411 let slot = self
412 .slots
413 .get(index)
414 .expect("get_group_scope: index out of bounds");
415 match slot {
416 Slot::Group { scope, .. } => *scope,
417 _ => None,
418 }
419 }
420
421 pub fn set_group_scope(&mut self, index: usize, scope: ScopeId) {
422 let slot = self
423 .slots
424 .get_mut(index)
425 .expect("set_group_scope: index out of bounds");
426 match slot {
427 Slot::Group {
428 scope: scope_opt, ..
429 } => {
430 *scope_opt = Some(scope);
433 }
434 _ => panic!("set_group_scope: slot at index is not a group"),
435 }
436 }
437
438 pub fn find_group_index_by_scope(&self, scope: ScopeId) -> Option<usize> {
439 self.slots
440 .iter()
441 .enumerate()
442 .find_map(|(i, slot)| match slot {
443 Slot::Group {
444 scope: Some(id), ..
445 } if *id == scope => Some(i),
446 _ => None,
447 })
448 }
449
450 pub fn start_recranpose_at_scope(&mut self, scope: ScopeId) -> Option<usize> {
451 let index = self.find_group_index_by_scope(scope)?;
452 self.start_recompose(index);
453 Some(index)
454 }
455
456 pub fn debug_dump_groups(&self) -> Vec<(usize, Key, Option<ScopeId>, usize)> {
457 self.slots
458 .iter()
459 .enumerate()
460 .filter_map(|(i, slot)| match slot {
461 Slot::Group {
462 key, len, scope, ..
463 } => Some((i, *key, *scope, *len)),
464 _ => None,
465 })
466 .collect()
467 }
468
469 pub fn debug_dump_all_slots(&self) -> Vec<(usize, String)> {
470 self.slots
471 .iter()
472 .enumerate()
473 .map(|(i, slot)| {
474 let kind = match slot {
475 Slot::Group {
476 key, scope, len, ..
477 } => format!("Group(key={:?}, scope={:?}, len={})", key, scope, len),
478 Slot::Value { .. } => "Value".to_string(),
479 Slot::Node { id, .. } => format!("Node(id={:?})", id),
480 Slot::Gap {
481 group_key,
482 group_scope,
483 ..
484 } => {
485 if let Some(key) = group_key {
486 format!("Gap(was_group_key={:?}, scope={:?})", key, group_scope)
487 } else {
488 "Gap".to_string()
489 }
490 }
491 };
492 (i, kind)
493 })
494 .collect()
495 }
496
497 fn update_group_bounds(&mut self) {
498 for frame in &mut self.group_stack {
499 if frame.end < self.cursor {
500 frame.end = self.cursor;
501 }
502 }
503 }
504
505 fn rebuild_all_anchor_positions(&mut self) {
508 let mut max_anchor = 0usize;
509 for slot in &self.slots {
510 let idx = slot.anchor_id().0;
511 if idx > max_anchor {
512 max_anchor = idx;
513 }
514 }
515 if self.anchors.len() <= max_anchor {
516 self.anchors.resize(max_anchor + 1, INVALID_ANCHOR_POS);
517 }
518
519 for pos in &mut self.anchors {
520 *pos = INVALID_ANCHOR_POS;
521 }
522
523 for (position, slot) in self.slots.iter().enumerate() {
524 let idx = slot.anchor_id().0;
525 if idx == 0 {
526 continue;
527 }
528 self.anchors[idx] = position;
529 }
530 }
531
532 fn shift_group_frames(&mut self, index: usize, delta: isize) {
533 if delta == 0 {
534 return;
535 }
536 if delta > 0 {
537 let delta = delta as usize;
538 for frame in &mut self.group_stack {
539 if frame.start >= index {
540 frame.start += delta;
541 frame.end += delta;
542 } else if frame.end >= index {
543 frame.end += delta;
544 }
545 }
546 } else {
547 let delta = (-delta) as usize;
548 for frame in &mut self.group_stack {
549 if frame.start >= index {
550 frame.start = frame.start.saturating_sub(delta);
551 frame.end = frame.end.saturating_sub(delta);
552 } else if frame.end > index {
553 frame.end = frame.end.saturating_sub(delta);
554 }
555 }
556 }
557 }
558
559 pub fn start(&mut self, key: Key) -> usize {
560 self.ensure_capacity();
561
562 let cursor = self.cursor;
563 let parent_force = self
564 .group_stack
565 .last()
566 .map(|frame| frame.force_children_recompose)
567 .unwrap_or(false);
568
569 if let Some(Slot::Group {
571 key: existing_key,
572 len,
573 has_gap_children,
574 ..
575 }) = self.slots.get(cursor)
576 {
577 if *existing_key == key && !*has_gap_children && !parent_force {
582 self.last_start_was_gap = false;
583
584 let frame = GroupFrame {
585 key,
586 start: cursor,
587 end: cursor + *len,
588 force_children_recompose: false,
589 };
590 self.group_stack.push(frame);
591 self.cursor = cursor + 1;
592 self.update_group_bounds();
593 return cursor;
594 }
595 }
596
597 if parent_force {
599 if let Some(Slot::Group {
600 key: existing_key,
601 len,
602 has_gap_children,
603 ..
604 }) = self.slots.get_mut(cursor)
605 {
606 if *existing_key == key {
607 *has_gap_children = false;
608 self.last_start_was_gap = true;
609 let frame = GroupFrame {
610 key,
611 start: cursor,
612 end: cursor + *len,
613 force_children_recompose: true,
614 };
615 self.group_stack.push(frame);
616 self.cursor = cursor + 1;
617 self.update_group_bounds();
618 return cursor;
619 }
620 }
621
622 if let Some(Slot::Gap {
623 anchor,
624 group_key: Some(gap_key),
625 group_scope,
626 group_len,
627 }) = self.slots.get(cursor)
628 {
629 if *gap_key == key {
630 let anchor = *anchor;
631 let gap_len = *group_len;
632 let preserved_scope = *group_scope;
633 self.slots[cursor] = Slot::Group {
634 key,
635 anchor,
636 len: gap_len,
637 scope: preserved_scope,
638 has_gap_children: false,
639 };
640 self.register_anchor(anchor, cursor);
641 self.last_start_was_gap = true;
642 let frame = GroupFrame {
643 key,
644 start: cursor,
645 end: cursor + gap_len,
646 force_children_recompose: true,
647 };
648 self.group_stack.push(frame);
649 self.cursor = cursor + 1;
650 self.update_group_bounds();
651 return cursor;
652 }
653 }
654
655 return self.insert_new_group_at_cursor(key);
656 }
657
658 self.last_start_was_gap = false;
659 let cursor = self.cursor;
660 debug_assert!(
661 cursor <= self.slots.len(),
662 "slot cursor {} out of bounds",
663 cursor
664 );
665
666 if cursor == self.slots.len() {
667 self.grow_slots();
668 }
669
670 debug_assert!(
671 cursor < self.slots.len(),
672 "slot cursor {} failed to grow",
673 cursor
674 );
675
676 if cursor > 0 && !matches!(self.slots.get(cursor), Some(Slot::Gap { .. })) {
677 if let Some(Slot::Group { key: prev_key, .. }) = self.slots.get(cursor - 1) {
678 if *prev_key == key {
679 return self.insert_new_group_at_cursor(key);
680 }
681 }
682 }
683
684 if let Some(slot) = self.slots.get_mut(cursor) {
686 if let Slot::Group {
687 key: existing_key,
688 len,
689 has_gap_children,
690 ..
691 } = slot
692 {
693 if *existing_key == key {
694 let group_len = *len;
695 let had_gap_children = *has_gap_children;
696 if had_gap_children {
697 *has_gap_children = false;
698 }
699 let force_children = had_gap_children || parent_force;
700
701 self.last_start_was_gap = false;
702 let frame = GroupFrame {
703 key,
704 start: cursor,
705 end: cursor + group_len,
706 force_children_recompose: force_children,
707 };
708 self.group_stack.push(frame);
709 self.cursor = cursor + 1;
710 self.update_group_bounds();
711 return cursor;
712 }
713 }
714 }
715
716 let mut reused_from_gap = false;
718 let reuse_result = match self.slots.get(cursor) {
719 Some(Slot::Group {
724 key: existing_key,
725 anchor: old_anchor,
726 len: old_len,
727 scope: old_scope,
728 has_gap_children: _,
729 }) if *existing_key != key => {
730 let old_key = *existing_key;
732 let old_anchor_val = *old_anchor;
733 let old_len_val = *old_len;
734 let old_scope_val = *old_scope;
735
736 let group_len = old_len_val.max(1);
738 if group_len > 1 {
739 let start = cursor + 1;
740 let end = cursor + group_len;
741 let _ = self.mark_range_as_gaps(start, end, Some(cursor));
742 }
743
744 self.slots[cursor] = Slot::Gap {
746 anchor: old_anchor_val,
747 group_key: Some(old_key),
748 group_scope: old_scope_val,
749 group_len: old_len_val,
750 };
751 None
753 }
754 Some(Slot::Gap {
757 anchor,
758 group_key: Some(gap_key),
759 group_scope,
760 group_len,
761 }) if *gap_key == key => {
762 reused_from_gap = true;
764 Some((*group_len, *anchor, *group_scope))
765 }
766 Some(_slot) => None,
767 None => None,
768 };
769 if let Some((len, group_anchor, preserved_scope)) = reuse_result {
770 if matches!(self.slots.get(cursor), Some(Slot::Gap { .. })) {
772 self.slots[cursor] = Slot::Group {
773 key,
774 anchor: group_anchor,
775 len,
776 scope: preserved_scope,
777 has_gap_children: false,
778 };
779 self.register_anchor(group_anchor, cursor);
780 }
781
782 if reused_from_gap {
783 if let Some(Slot::Group {
784 has_gap_children, ..
785 }) = self.slots.get_mut(cursor)
786 {
787 *has_gap_children = false;
788 }
789 }
790
791 self.last_start_was_gap = reused_from_gap || parent_force;
792 let frame = GroupFrame {
793 key,
794 start: cursor,
795 end: cursor + len,
796 force_children_recompose: reused_from_gap || parent_force,
797 };
798 self.group_stack.push(frame);
799 self.cursor = cursor + 1;
800 self.update_group_bounds();
801 return cursor;
802 }
803
804 let allow_rescue = !parent_force && cursor < self.slots.len().saturating_sub(1);
805 if !allow_rescue {
806 return self.insert_new_group_at_cursor(key);
807 }
808
809 let parent_end = self
817 .group_stack
818 .last()
819 .map(|frame| frame.end.min(self.slots.len()))
820 .unwrap_or(self.slots.len());
821
822 let needs_extended_search = parent_end < self.slots.len();
825
826 let mut search_index = cursor;
827 let mut found_group: Option<(usize, AnchorId, usize, Option<ScopeId>)> = None;
828 const SEARCH_BUDGET: usize = 16;
829 let mut scanned = 0usize;
830 while search_index < parent_end && scanned < SEARCH_BUDGET {
831 scanned += 1;
832 match self.slots.get(search_index) {
833 Some(Slot::Group {
834 key: existing_key,
835 anchor,
836 len,
837 scope: _,
838 ..
839 }) => {
840 let group_len = *len;
841 if *existing_key == key {
842 found_group = Some((search_index, *anchor, group_len, None));
843 break;
844 }
845 let mut child_index = search_index + 1;
849 let search_limit = (search_index + group_len).min(self.slots.len());
850 while child_index < search_limit {
851 match self.slots.get(child_index) {
852 Some(Slot::Gap {
853 anchor: gap_anchor,
854 group_key: Some(gap_key),
855 group_scope,
856 group_len: gap_len,
857 }) if *gap_key == key => {
858 found_group =
860 Some((child_index, *gap_anchor, *gap_len, *group_scope));
861 break;
862 }
863 Some(Slot::Gap {
864 group_len: gap_len, ..
865 }) => {
866 child_index += (*gap_len).max(1);
869 }
870 Some(Slot::Group {
871 len: nested_len, ..
872 }) => {
873 child_index += (*nested_len).max(1);
875 }
876 _ => {
877 child_index += 1;
878 }
879 }
880 }
881 if found_group.is_some() {
882 break;
883 }
884 let advance = group_len.max(1);
885 search_index = search_index.saturating_add(advance);
886 }
887 Some(Slot::Gap {
889 anchor,
890 group_key: Some(gap_key),
891 group_scope,
892 group_len,
893 }) => {
894 if *gap_key == key {
895 found_group = Some((search_index, *anchor, *group_len, *group_scope));
896 break;
897 }
898 let gap_len_val = *group_len;
901 let mut child_index = search_index + 1;
902 let search_limit = (search_index + gap_len_val).min(self.slots.len());
903 while child_index < search_limit {
904 match self.slots.get(child_index) {
905 Some(Slot::Gap {
906 anchor: child_gap_anchor,
907 group_key: Some(child_gap_key),
908 group_scope: child_group_scope,
909 group_len: child_gap_len,
910 }) if *child_gap_key == key => {
911 found_group = Some((
913 child_index,
914 *child_gap_anchor,
915 *child_gap_len,
916 *child_group_scope,
917 ));
918 break;
919 }
920 Some(Slot::Gap {
921 group_len: nested_gap_len,
922 ..
923 }) => {
924 child_index += (*nested_gap_len).max(1);
926 }
927 Some(Slot::Group {
928 len: nested_len, ..
929 }) => {
930 child_index += (*nested_len).max(1);
932 }
933 _ => {
934 child_index += 1;
935 }
936 }
937 }
938 if found_group.is_some() {
939 break;
940 }
941 let advance = gap_len_val.max(1);
942 search_index = search_index.saturating_add(advance);
943 }
944 Some(_slot) => {
945 search_index += 1;
946 }
947 None => break,
948 }
949 }
950
951 if found_group.is_none() && needs_extended_search {
961 search_index = parent_end;
962 const EXTENDED_SEARCH_BUDGET: usize = 16;
963 let mut extended_scanned = 0usize;
964 while search_index < self.slots.len() && extended_scanned < EXTENDED_SEARCH_BUDGET {
965 extended_scanned += 1;
966 match self.slots.get(search_index) {
967 Some(Slot::Group {
969 key: existing_key,
970 anchor,
971 len,
972 scope,
973 ..
974 }) => {
975 if *existing_key == key {
976 found_group = Some((search_index, *anchor, *len, *scope));
977 break;
978 }
979 let advance = (*len).max(1);
980 search_index = search_index.saturating_add(advance);
981 }
982 Some(Slot::Gap {
984 anchor,
985 group_key: Some(gap_key),
986 group_scope,
987 group_len,
988 }) => {
989 if *gap_key == key {
990 found_group = Some((search_index, *anchor, *group_len, *group_scope));
991 break;
992 }
993 let advance = (*group_len).max(1);
994 search_index = search_index.saturating_add(advance);
995 }
996 Some(_slot) => {
997 search_index += 1;
998 }
999 None => break,
1000 }
1001 }
1002 }
1003
1004 if let Some((found_index, group_anchor, group_len, preserved_scope)) = found_group {
1005 let reused_gap = matches!(self.slots.get(found_index), Some(Slot::Gap { .. }));
1007 if reused_gap {
1008 self.slots[found_index] = Slot::Group {
1009 key,
1010 anchor: group_anchor,
1011 len: group_len,
1012 scope: preserved_scope,
1013 has_gap_children: false,
1014 };
1015 }
1016
1017 self.last_start_was_gap = reused_gap || parent_force;
1018 let group_extent = group_len.max(1);
1019 let available = self.slots.len().saturating_sub(found_index);
1020 let actual_len = group_extent.min(available);
1021 if actual_len > 0 {
1022 self.shift_group_frames(found_index, -(actual_len as isize));
1023 let moved: Vec<_> = self
1024 .slots
1025 .drain(found_index..found_index + actual_len)
1026 .collect();
1027 self.shift_group_frames(cursor, moved.len() as isize);
1028 self.slots.splice(cursor..cursor, moved);
1029 self.anchors_dirty = true;
1031 let frame = GroupFrame {
1032 key,
1033 start: cursor,
1034 end: cursor + actual_len,
1035 force_children_recompose: reused_gap || parent_force,
1036 };
1037 self.group_stack.push(frame);
1038 self.cursor = cursor + 1;
1039 self.update_group_bounds();
1040 return cursor;
1041 } else {
1042 self.shift_group_frames(found_index, 0);
1044 }
1045 }
1046
1047 self.insert_new_group_at_cursor(key)
1048 }
1049
1050 fn insert_new_group_at_cursor(&mut self, key: Key) -> usize {
1051 self.ensure_capacity();
1053
1054 let cursor = self.cursor;
1055 self.ensure_gap_at_local(cursor);
1056 let parent_force = self
1057 .group_stack
1058 .last()
1059 .map(|frame| frame.force_children_recompose)
1060 .unwrap_or(false);
1061
1062 if cursor < self.slots.len() {
1063 debug_assert!(matches!(self.slots[cursor], Slot::Gap { .. }));
1064 let group_anchor = self.allocate_anchor();
1065 self.slots[cursor] = Slot::Group {
1066 key,
1067 anchor: group_anchor,
1068 len: 0,
1069 scope: None,
1070 has_gap_children: false,
1071 };
1072 self.register_anchor(group_anchor, cursor);
1073 } else {
1074 let group_anchor = self.allocate_anchor();
1075 self.slots.push(Slot::Group {
1076 key,
1077 anchor: group_anchor,
1078 len: 0,
1079 scope: None,
1080 has_gap_children: false,
1081 });
1082 self.register_anchor(group_anchor, cursor);
1083 }
1084 self.last_start_was_gap = parent_force;
1085 self.cursor = cursor + 1;
1086 self.group_stack.push(GroupFrame {
1087 key,
1088 start: cursor,
1089 end: self.cursor,
1090 force_children_recompose: parent_force,
1091 });
1092 self.update_group_bounds();
1093 cursor
1094 }
1095 fn shift_anchor_positions_from(&mut self, start_slot: usize, delta: isize) {
1096 for pos in &mut self.anchors {
1097 if *pos != INVALID_ANCHOR_POS && *pos >= start_slot {
1098 *pos = (*pos as isize + delta) as usize;
1099 }
1100 }
1101 }
1102 fn flush_anchors_if_dirty(&mut self) {
1103 if self.anchors_dirty {
1104 self.anchors_dirty = false;
1105 self.rebuild_all_anchor_positions();
1106 }
1107 }
1108 pub fn end(&mut self) {
1109 if let Some(frame) = self.group_stack.pop() {
1110 let end = self.cursor;
1111 if let Some(slot) = self.slots.get_mut(frame.start) {
1112 debug_assert_eq!(
1113 SlotKind::Group,
1114 slot.kind(),
1115 "slot kind mismatch at {}",
1116 frame.start
1117 );
1118 if let Slot::Group {
1119 key,
1120 len,
1121 has_gap_children,
1122 ..
1123 } = slot
1124 {
1125 debug_assert_eq!(*key, frame.key, "group key mismatch");
1126 let new_len = end.saturating_sub(frame.start);
1128 let old_len = *len;
1129 if new_len < old_len {
1130 *has_gap_children = true;
1131 }
1132 const SHRINK_MIN_DROP: usize = 64;
1133 const SHRINK_RATIO: usize = 4;
1134 if old_len > new_len
1135 && old_len >= new_len.saturating_mul(SHRINK_RATIO)
1136 && (old_len - new_len) >= SHRINK_MIN_DROP
1137 {
1138 *len = new_len;
1139 } else {
1140 *len = old_len.max(new_len);
1141 }
1142 }
1143 }
1144 if let Some(parent) = self.group_stack.last_mut() {
1145 if parent.end < end {
1146 parent.end = end;
1147 }
1148 }
1149 }
1150 }
1151
1152 fn start_recompose(&mut self, index: usize) {
1153 if let Some(slot) = self.slots.get(index) {
1154 debug_assert_eq!(
1155 SlotKind::Group,
1156 slot.kind(),
1157 "slot kind mismatch at {}",
1158 index
1159 );
1160 if let Slot::Group { key, len, .. } = *slot {
1161 let frame = GroupFrame {
1162 key,
1163 start: index,
1164 end: index + len,
1165 force_children_recompose: false,
1166 };
1167 self.group_stack.push(frame);
1168 self.cursor = index + 1;
1169 if self.cursor < self.slots.len()
1170 && matches!(self.slots.get(self.cursor), Some(Slot::Value { .. }))
1171 {
1172 self.cursor += 1;
1173 }
1174 }
1175 }
1176 }
1177
1178 fn end_recompose(&mut self) {
1179 if let Some(frame) = self.group_stack.pop() {
1180 self.cursor = frame.end;
1181 }
1182 }
1183
1184 pub fn skip_current(&mut self) {
1185 if let Some(frame) = self.group_stack.last() {
1186 self.cursor = frame.end.min(self.slots.len());
1187 }
1188 }
1189
1190 pub fn node_ids_in_current_group(&self) -> Vec<NodeId> {
1191 let Some(frame) = self.group_stack.last() else {
1192 return Vec::new();
1193 };
1194 let end = frame.end.min(self.slots.len());
1195 self.slots[frame.start..end]
1196 .iter()
1197 .filter_map(|slot| match slot {
1198 Slot::Node { id, .. } => Some(*id),
1199 _ => None,
1200 })
1201 .collect()
1202 }
1203
1204 pub fn use_value_slot<T: 'static>(&mut self, init: impl FnOnce() -> T) -> usize {
1205 self.ensure_capacity();
1206
1207 let cursor = self.cursor;
1208 debug_assert!(
1209 cursor <= self.slots.len(),
1210 "slot cursor {} out of bounds",
1211 cursor
1212 );
1213
1214 if cursor < self.slots.len() {
1215 let reuse = matches!(
1217 self.slots.get(cursor),
1218 Some(Slot::Value { data, .. }) if data.is::<T>()
1219 );
1220 if reuse {
1221 self.cursor = cursor + 1;
1222 self.update_group_bounds();
1223 return cursor;
1224 }
1225
1226 if matches!(self.slots.get(cursor), Some(Slot::Gap { .. })) {
1228 let anchor = self.allocate_anchor();
1229 let boxed: Box<dyn Any> = Box::new(init());
1230 self.slots[cursor] = Slot::Value {
1231 anchor,
1232 data: boxed,
1233 };
1234 self.register_anchor(anchor, cursor);
1235 self.cursor = cursor + 1;
1236 self.update_group_bounds();
1237 return cursor;
1238 }
1239
1240 let anchor = self.allocate_anchor();
1243 let boxed: Box<dyn Any> = Box::new(init());
1244 self.slots[cursor] = Slot::Value {
1245 anchor,
1246 data: boxed,
1247 };
1248 self.register_anchor(anchor, cursor);
1249 self.cursor = cursor + 1;
1250 self.update_group_bounds();
1251 return cursor;
1252 }
1253
1254 let anchor = self.allocate_anchor();
1256 let boxed: Box<dyn Any> = Box::new(init());
1257 let slot = Slot::Value {
1258 anchor,
1259 data: boxed,
1260 };
1261 self.slots.push(slot);
1262 self.register_anchor(anchor, cursor);
1263 self.cursor = cursor + 1;
1264 self.update_group_bounds();
1265 cursor
1266 }
1267
1268 pub fn read_value<T: 'static>(&self, idx: usize) -> &T {
1269 let slot = self
1270 .slots
1271 .get(idx)
1272 .unwrap_or_else(|| panic!("slot index {} out of bounds", idx));
1273 debug_assert_eq!(
1274 SlotKind::Value,
1275 slot.kind(),
1276 "slot kind mismatch at {}",
1277 idx
1278 );
1279 slot.as_value()
1280 }
1281
1282 pub fn read_value_mut<T: 'static>(&mut self, idx: usize) -> &mut T {
1283 let slot = self
1284 .slots
1285 .get_mut(idx)
1286 .unwrap_or_else(|| panic!("slot index {} out of bounds", idx));
1287 debug_assert_eq!(
1288 SlotKind::Value,
1289 slot.kind(),
1290 "slot kind mismatch at {}",
1291 idx
1292 );
1293 slot.as_value_mut()
1294 }
1295
1296 pub fn write_value<T: 'static>(&mut self, idx: usize, value: T) {
1297 if idx >= self.slots.len() {
1298 panic!("attempted to write slot {} out of bounds", idx);
1299 }
1300 let slot = &mut self.slots[idx];
1301 debug_assert_eq!(
1302 SlotKind::Value,
1303 slot.kind(),
1304 "slot kind mismatch at {}",
1305 idx
1306 );
1307 let anchor = slot.anchor_id();
1309 *slot = Slot::Value {
1310 anchor,
1311 data: Box::new(value),
1312 };
1313 }
1314
1315 pub fn read_value_by_anchor<T: 'static>(&self, anchor: AnchorId) -> Option<&T> {
1318 let idx = self.resolve_anchor(anchor)?;
1319 Some(self.read_value(idx))
1320 }
1321
1322 pub fn read_value_mut_by_anchor<T: 'static>(&mut self, anchor: AnchorId) -> Option<&mut T> {
1324 let idx = self.resolve_anchor(anchor)?;
1325 Some(self.read_value_mut(idx))
1326 }
1327
1328 pub fn remember<T: 'static>(&mut self, init: impl FnOnce() -> T) -> Owned<T> {
1329 let index = self.use_value_slot(|| Owned::new(init()));
1330 self.read_value::<Owned<T>>(index).clone()
1331 }
1332
1333 pub fn remember_with_anchor<T: 'static>(
1336 &mut self,
1337 init: impl FnOnce() -> T,
1338 ) -> (usize, AnchorId) {
1339 let index = self.use_value_slot(|| Owned::new(init()));
1340 let anchor = self
1341 .slots
1342 .get(index)
1343 .map(|slot| slot.anchor_id())
1344 .unwrap_or(AnchorId::INVALID);
1345 (index, anchor)
1346 }
1347
1348 pub fn record_node(&mut self, id: NodeId) {
1349 self.ensure_capacity();
1350
1351 let cursor = self.cursor;
1352 debug_assert!(
1353 cursor <= self.slots.len(),
1354 "slot cursor {} out of bounds",
1355 cursor
1356 );
1357 if cursor < self.slots.len() {
1358 if let Some(Slot::Node { id: existing, .. }) = self.slots.get(cursor) {
1360 if *existing == id {
1361 self.cursor = cursor + 1;
1362 self.update_group_bounds();
1363 return;
1364 }
1365 }
1366
1367 if matches!(self.slots.get(cursor), Some(Slot::Gap { .. })) {
1369 let anchor = self.allocate_anchor();
1370 self.slots[cursor] = Slot::Node { anchor, id };
1371 self.register_anchor(anchor, cursor);
1372 self.cursor = cursor + 1;
1373 self.update_group_bounds();
1374 return;
1375 }
1376
1377 let anchor = self.allocate_anchor();
1381 self.slots[cursor] = Slot::Node { anchor, id };
1382 self.register_anchor(anchor, cursor);
1383 self.cursor = cursor + 1;
1384 self.update_group_bounds();
1385 return;
1386 }
1387
1388 let anchor = self.allocate_anchor();
1390 let slot = Slot::Node { anchor, id };
1391 self.slots.push(slot);
1392 self.register_anchor(anchor, cursor);
1393 self.cursor = cursor + 1;
1394 self.update_group_bounds();
1395 }
1396
1397 pub fn peek_node(&self) -> Option<NodeId> {
1398 let cursor = self.cursor;
1399 debug_assert!(
1400 cursor <= self.slots.len(),
1401 "slot cursor {} out of bounds",
1402 cursor
1403 );
1404 match self.slots.get(cursor) {
1405 Some(Slot::Node { id, .. }) => Some(*id),
1406 Some(_slot) => None,
1407 None => None,
1408 }
1409 }
1410
1411 pub fn read_node(&mut self) -> Option<NodeId> {
1412 let cursor = self.cursor;
1413 debug_assert!(
1414 cursor <= self.slots.len(),
1415 "slot cursor {} out of bounds",
1416 cursor
1417 );
1418 let node = match self.slots.get(cursor) {
1419 Some(Slot::Node { id, .. }) => Some(*id),
1420 Some(_slot) => None,
1421 None => None,
1422 };
1423 if node.is_some() {
1424 self.cursor = cursor + 1;
1425 self.update_group_bounds();
1426 }
1427 node
1428 }
1429
1430 pub fn advance_after_node_read(&mut self) {
1431 self.cursor += 1;
1432 self.update_group_bounds();
1433 }
1434
1435 pub fn reset(&mut self) {
1436 self.cursor = 0;
1437 self.group_stack.clear();
1438 }
1439
1440 pub fn step_back(&mut self) {
1443 debug_assert!(self.cursor > 0, "Cannot step back from cursor 0");
1444 self.cursor = self.cursor.saturating_sub(1);
1445 }
1446
1447 pub fn trim_to_cursor(&mut self) -> bool {
1461 let mut marked = false;
1462 if let Some((owner_start, group_end)) = self
1463 .group_stack
1464 .last()
1465 .map(|frame| (frame.start, frame.end.min(self.slots.len())))
1466 {
1467 if self.cursor < group_end
1469 && self.mark_range_as_gaps(self.cursor, group_end, Some(owner_start))
1470 {
1471 marked = true;
1472 }
1473
1474 if let Some(frame) = self.group_stack.last_mut() {
1479 frame.end = self.cursor;
1480 }
1481 } else if self.cursor < self.slots.len() {
1482 if self.mark_range_as_gaps(self.cursor, self.slots.len(), None) {
1485 marked = true;
1486 }
1487 }
1488 marked
1489 }
1490}
1491
1492impl SlotStorage for SlotTable {
1509 type Group = GroupId;
1510 type ValueSlot = ValueSlotId;
1511
1512 fn begin_group(&mut self, key: Key) -> StartGroup<Self::Group> {
1513 let idx = SlotTable::start(self, key);
1514 let restored = SlotTable::take_last_start_was_gap(self);
1515 StartGroup {
1516 group: GroupId(idx),
1517 restored_from_gap: restored,
1518 }
1519 }
1520
1521 fn set_group_scope(&mut self, group: Self::Group, scope: ScopeId) {
1522 SlotTable::set_group_scope(self, group.0, scope);
1523 }
1524
1525 fn end_group(&mut self) {
1526 SlotTable::end(self);
1527 }
1528
1529 fn skip_current_group(&mut self) {
1530 SlotTable::skip_current(self);
1531 }
1532
1533 fn nodes_in_current_group(&self) -> Vec<NodeId> {
1534 SlotTable::node_ids_in_current_group(self)
1535 }
1536
1537 fn begin_recranpose_at_scope(&mut self, scope: ScopeId) -> Option<Self::Group> {
1538 SlotTable::start_recranpose_at_scope(self, scope).map(GroupId)
1539 }
1540
1541 fn end_recompose(&mut self) {
1542 SlotTable::end_recompose(self);
1543 }
1544
1545 fn alloc_value_slot<T: 'static>(&mut self, init: impl FnOnce() -> T) -> Self::ValueSlot {
1546 let idx = SlotTable::use_value_slot(self, init);
1547 ValueSlotId(idx)
1548 }
1549
1550 fn read_value<T: 'static>(&self, slot: Self::ValueSlot) -> &T {
1551 SlotTable::read_value(self, slot.0)
1552 }
1553
1554 fn read_value_mut<T: 'static>(&mut self, slot: Self::ValueSlot) -> &mut T {
1555 SlotTable::read_value_mut(self, slot.0)
1556 }
1557
1558 fn write_value<T: 'static>(&mut self, slot: Self::ValueSlot, value: T) {
1559 SlotTable::write_value(self, slot.0, value);
1560 }
1561
1562 fn remember<T: 'static>(&mut self, init: impl FnOnce() -> T) -> Owned<T> {
1563 SlotTable::remember(self, init)
1564 }
1565
1566 fn peek_node(&self) -> Option<NodeId> {
1567 SlotTable::peek_node(self)
1568 }
1569
1570 fn record_node(&mut self, id: NodeId) {
1571 SlotTable::record_node(self, id);
1572 }
1573
1574 fn advance_after_node_read(&mut self) {
1575 SlotTable::advance_after_node_read(self);
1576 }
1577
1578 fn step_back(&mut self) {
1579 SlotTable::step_back(self);
1580 }
1581
1582 fn finalize_current_group(&mut self) -> bool {
1583 SlotTable::trim_to_cursor(self)
1584 }
1585
1586 fn reset(&mut self) {
1587 SlotTable::reset(self);
1588 }
1589
1590 fn flush(&mut self) {
1591 SlotTable::flush_anchors_if_dirty(self);
1592 }
1593}