1use core::hash::BuildHasher;
2use core::hash::Hash;
3
4use crate::Ptr;
5use crate::arena::ActiveSlotRef;
6use crate::linked_hash_map::Entry;
7use crate::linked_hash_map::Iter;
8use crate::linked_hash_map::LinkedHashMap;
9use crate::linked_hash_map::RemovedEntry;
10
11#[derive(Debug)]
12pub struct CursorMut<'m, K, T, S> {
39 pub(crate) ptr: Option<ActiveSlotRef<K, T>>,
40 pub(crate) map: &'m mut LinkedHashMap<K, T, S>,
41}
42
43impl<'m, K: Hash + Eq, T, S: BuildHasher> CursorMut<'m, K, T, S> {
44 #[inline]
47 pub fn insert_after_move_to(
48 &mut self,
49 key: K,
50 value: T,
51 ) -> Option<T> {
52 let ptr = if self.ptr.is_none() {
53 self.map.head_tail.as_ref().map(|ht| ht.tail)
54 } else {
55 self.ptr
56 };
57
58 match self.map.entry(key) {
59 Entry::Occupied(occupied_entry) => {
60 let mut map_ptr = *occupied_entry.entry.get();
61 if Some(map_ptr) != ptr {
62 self.map.move_after_internal(map_ptr, ptr.unwrap());
63 }
64 self.ptr = Some(map_ptr);
65 Some(core::mem::replace(
66 &mut map_ptr.data_mut(&mut self.map.nodes).value,
67 value,
68 ))
69 }
70 Entry::Vacant(vacant_entry) => {
71 self.ptr = Some(vacant_entry.insert_after_internal(value, ptr).0);
72 None
73 }
74 }
75 }
76
77 #[inline]
80 pub fn insert_before_move_to(
81 &mut self,
82 key: K,
83 value: T,
84 ) -> Option<T> {
85 let ptr = if self.ptr.is_none() {
86 self.map.head_tail.as_ref().map(|ht| ht.head)
87 } else {
88 self.ptr
89 };
90
91 match self.map.entry(key) {
92 Entry::Occupied(occupied_entry) => {
93 let mut map_ptr = *occupied_entry.entry.get();
94 if Some(map_ptr) != ptr {
95 self.map.move_before_internal(map_ptr, ptr.unwrap());
96 }
97 self.ptr = Some(map_ptr);
98 Some(core::mem::replace(
99 &mut map_ptr.data_mut(&mut self.map.nodes).value,
100 value,
101 ))
102 }
103 Entry::Vacant(vacant_entry) => {
104 self.ptr = Some(vacant_entry.insert_before_internal(value, ptr).0);
105 None
106 }
107 }
108 }
109
110 #[inline]
124 pub fn get_ptr(
125 &self,
126 key: &K,
127 ) -> Option<Ptr> {
128 self.map.get_ptr(key)
129 }
130}
131
132impl<'m, K: Hash + Eq, T, S: BuildHasher> CursorMut<'m, K, T, S> {
133 #[inline]
135 pub fn remove_prev(&mut self) -> Option<(Ptr, RemovedEntry<K, T>)> {
136 let prev = self.ptr.map(|slot| slot.prev(&self.map.nodes))?;
137 if Some(prev) == self.ptr {
138 self.ptr = None;
142 }
143 Some(self.map.remove_ptr_internal(prev))
144 }
145
146 #[inline]
148 pub fn remove_next(&mut self) -> Option<(Ptr, RemovedEntry<K, T>)> {
149 let next = self.ptr.map(|slot| slot.next(&self.map.nodes))?;
150 if Some(next) == self.ptr {
151 self.ptr = None;
152 }
153 Some(self.map.remove_ptr_internal(next))
154 }
155
156 #[inline]
158 pub fn remove(self) -> Option<(Ptr, RemovedEntry<K, T>)> {
159 let ptr = self.ptr?;
160 Some(self.map.remove_ptr_internal(ptr))
161 }
162}
163
164impl<'m, K, T, S> CursorMut<'m, K, T, S> {
165 #[inline]
167 pub fn iter(&self) -> Iter<'_, K, T> {
168 Iter {
169 forward_ptr: self.ptr,
170 reverse_ptr: self.ptr.map(|slot| slot.prev(&self.map.nodes)),
171 nodes: &self.map.nodes,
172 }
173 }
174
175 #[inline]
179 pub fn move_next(&mut self) {
180 self.ptr = self.ptr.map(|slot| slot.next(&self.map.nodes));
181 }
182
183 #[inline]
187 pub fn move_prev(&mut self) {
188 self.ptr = self.ptr.map(|slot| slot.prev(&self.map.nodes));
189 }
190
191 #[inline]
193 pub fn ptr(&self) -> Option<Ptr> {
194 self.ptr.map(|slot| slot.this(&self.map.nodes))
195 }
196
197 #[inline]
199 pub fn at_tail(&self) -> bool {
200 self.ptr == self.map.head_tail.as_ref().map(|ht| ht.tail)
201 }
202
203 #[inline]
205 pub fn at_head(&self) -> bool {
206 self.ptr == self.map.head_tail.as_ref().map(|ht| ht.head)
207 }
208
209 #[inline]
211 pub fn current(&self) -> Option<(&K, &T)> {
212 let ptr = self.ptr?;
213 let data = ptr.data(&self.map.nodes);
214 Some((&data.key, &data.value))
215 }
216
217 #[inline]
245 pub fn current_mut(&mut self) -> Option<(&K, &mut T)> {
246 let mut ptr = self.ptr?;
247 let data = ptr.data_mut(&mut self.map.nodes);
248 Some((&data.key, &mut data.value))
249 }
250
251 #[inline]
274 pub fn next_ptr(&self) -> Option<Ptr> {
275 self.ptr
276 .map(|slot| slot.next(&self.map.nodes).this(&self.map.nodes))
277 }
278
279 #[inline]
306 pub fn next(&self) -> Option<(&K, &T)> {
307 let ptr = self.next_ptr()?;
308 self.map.ptr_get_entry(ptr)
309 }
310
311 #[inline]
340 pub fn next_mut(&mut self) -> Option<(&K, &mut T)> {
341 let ptr = self.next_ptr()?;
342 self.map.ptr_get_entry_mut(ptr)
343 }
344
345 #[inline]
368 pub fn prev_ptr(&self) -> Option<Ptr> {
369 self.ptr
370 .map(|slot| slot.prev(&self.map.nodes).this(&self.map.nodes))
371 }
372
373 #[inline]
400 pub fn prev(&self) -> Option<(&K, &T)> {
401 let ptr = self.prev_ptr()?;
402 self.map.ptr_get_entry(ptr)
403 }
404
405 #[inline]
434 pub fn prev_mut(&mut self) -> Option<(&K, &mut T)> {
435 let ptr = self.prev_ptr()?;
436 self.map.ptr_get_entry_mut(ptr)
437 }
438}
439
440#[cfg(test)]
441mod tests {
442 use alloc::vec;
443 use alloc::vec::Vec;
444
445 use crate::LinkedHashMap;
446
447 #[test]
448 fn test_cursor_insert_after_move_to_empty_map() {
449 let mut map = LinkedHashMap::new();
450 {
451 let mut cursor = map.head_cursor_mut();
452 assert_eq!(cursor.insert_after_move_to("first", 1), None);
453 assert_eq!(cursor.current(), Some((&"first", &1)));
454 assert!(cursor.at_head());
455 assert!(cursor.at_tail());
456 }
457 assert_eq!(map.len(), 1);
458 }
459
460 #[test]
461 fn test_cursor_insert_after_move_to_existing_key() {
462 let mut map = LinkedHashMap::new();
463 map.insert("a", 1);
464 map.insert("b", 2);
465
466 let mut cursor = map.head_cursor_mut();
467 let old_value = cursor.insert_after_move_to("aa", 10);
468
469 assert_eq!(old_value, None);
470 assert_eq!(cursor.current(), Some((&"aa", &10)));
471 assert_eq!(map.len(), 3);
472
473 let collected: Vec<_> = map.iter().map(|(k, v)| (*k, *v)).collect();
474 assert_eq!(collected, vec![("a", 1), ("aa", 10), ("b", 2)]);
475 }
476
477 #[test]
478 fn test_cursor_insert_after_move_to_new_key() {
479 let mut map = LinkedHashMap::new();
480 map.insert("a", 1);
481 map.insert("b", 2);
482
483 let mut cursor = map.head_cursor_mut();
484 assert_eq!(cursor.insert_after_move_to("c", 3), None);
485
486 assert_eq!(cursor.current(), Some((&"c", &3)));
487 assert_eq!(map.len(), 3);
488
489 let collected: Vec<_> = map.iter().map(|(k, v)| (*k, *v)).collect();
490 assert_eq!(collected, vec![("a", 1), ("c", 3), ("b", 2)]);
491 }
492
493 #[test]
494 fn test_cursor_insert_before_move_to_empty_map() {
495 let mut map = LinkedHashMap::new();
496 {
497 let mut cursor = map.tail_cursor_mut();
498 assert_eq!(cursor.insert_before_move_to("first", 1), None);
499 assert_eq!(cursor.current(), Some((&"first", &1)));
500 assert!(cursor.at_head());
501 assert!(cursor.at_tail());
502 }
503 assert_eq!(map.len(), 1);
504 }
505
506 #[test]
507 fn test_cursor_insert_before_move_to_existing_key() {
508 let mut map = LinkedHashMap::new();
509 map.insert("a", 1);
510 map.insert("b", 2);
511
512 let mut cursor = map.tail_cursor_mut();
513 let old_value = cursor.insert_before_move_to("a", 10);
514
515 assert_eq!(old_value, Some(1));
516 assert_eq!(cursor.current(), Some((&"a", &10)));
517 assert_eq!(map.len(), 2);
518
519 let collected: Vec<_> = map.iter().map(|(k, v)| (*k, *v)).collect();
520 assert_eq!(collected, vec![("a", 10), ("b", 2)]);
521 }
522
523 #[test]
524 fn test_cursor_insert_before_move_to_new_key() {
525 let mut map = LinkedHashMap::new();
526 map.insert("a", 1);
527 map.insert("b", 2);
528
529 let mut cursor = map.tail_cursor_mut();
530 assert_eq!(cursor.insert_before_move_to("c", 3), None);
531
532 assert_eq!(cursor.current(), Some((&"c", &3)));
533 assert_eq!(map.len(), 3);
534
535 let collected: Vec<_> = map.iter().map(|(k, v)| (*k, *v)).collect();
536 assert_eq!(collected, vec![("a", 1), ("c", 3), ("b", 2)]);
537 }
538
539 #[test]
540 fn test_cursor_remove_prev() {
541 let mut map = LinkedHashMap::new();
542 map.insert("a", 1);
543 map.insert("b", 2);
544 map.insert("c", 3);
545
546 {
547 let mut cursor = map.tail_cursor_mut();
548 let (_ptr, removed) = cursor.remove_prev().unwrap();
549
550 assert_eq!(removed.key, "b");
551 assert_eq!(removed.value, 2);
552 assert_eq!(cursor.current(), Some((&"c", &3)));
553 }
554 assert_eq!(map.len(), 2);
555 let collected: Vec<_> = map.iter().map(|(k, v)| (*k, *v)).collect();
556 assert_eq!(collected, vec![("a", 1), ("c", 3)]);
557 }
558
559 #[test]
560 fn test_cursor_remove_next() {
561 let mut map = LinkedHashMap::new();
562 map.insert("a", 1);
563 map.insert("b", 2);
564 map.insert("c", 3);
565
566 {
567 let mut cursor = map.head_cursor_mut();
568 let (_ptr, removed) = cursor.remove_next().unwrap();
569
570 assert_eq!(removed.key, "b");
571 assert_eq!(removed.value, 2);
572 assert_eq!(cursor.current(), Some((&"a", &1)));
573 }
574 assert_eq!(map.len(), 2);
575 let collected: Vec<_> = map.iter().map(|(k, v)| (*k, *v)).collect();
576 assert_eq!(collected, vec![("a", 1), ("c", 3)]);
577 }
578
579 #[test]
580 fn test_cursor_remove_current() {
581 let mut map = LinkedHashMap::new();
582 map.insert("a", 1);
583 map.insert("b", 2);
584 map.insert("c", 3);
585
586 {
587 let cursor = map.key_cursor_mut(&"b");
588 let (_ptr, removed) = cursor.remove().unwrap();
589
590 assert_eq!(removed.key, "b");
591 assert_eq!(removed.value, 2);
592 }
593 assert_eq!(map.len(), 2);
594 let collected: Vec<_> = map.iter().map(|(k, v)| (*k, *v)).collect();
595 assert_eq!(collected, vec![("a", 1), ("c", 3)]);
596 }
597
598 #[test]
599 fn test_cursor_remove_operations_empty_cases() {
600 let mut map = LinkedHashMap::new();
601 map.insert("only", 1);
602
603 let mut cursor = map.head_cursor_mut();
604 assert_ne!(cursor.remove_prev(), None);
605 assert!(cursor.remove_next().is_none());
606
607 let cursor = cursor.remove();
608 assert!(cursor.is_none());
609 assert_eq!(map.len(), 0);
610 }
611
612 #[test]
613 fn test_cursor_navigation_move_next_prev() {
614 let mut map = LinkedHashMap::new();
615 map.insert("a", 1);
616 map.insert("b", 2);
617 map.insert("c", 3);
618
619 let mut cursor = map.head_cursor_mut();
620 assert_eq!(cursor.current(), Some((&"a", &1)));
621 assert!(cursor.at_head());
622
623 cursor.move_next();
624 assert_eq!(cursor.current(), Some((&"b", &2)));
625 assert!(!cursor.at_head());
626 assert!(!cursor.at_tail());
627
628 cursor.move_next();
629 assert_eq!(cursor.current(), Some((&"c", &3)));
630 assert!(cursor.at_tail());
631
632 cursor.move_next();
633 assert_eq!(cursor.current(), Some((&"a", &1)));
634 assert!(cursor.at_head());
635
636 cursor.move_prev();
637 assert_eq!(cursor.current(), Some((&"c", &3)));
638 assert!(cursor.at_tail());
639
640 cursor.move_prev();
641 assert_eq!(cursor.current(), Some((&"b", &2)));
642 assert!(!cursor.at_head());
643 assert!(!cursor.at_tail());
644 }
645
646 #[test]
647 fn test_cursor_current_and_current_mut() {
648 let mut map = LinkedHashMap::new();
649 map.insert("test", 42);
650
651 let mut cursor = map.head_cursor_mut();
652 assert_eq!(cursor.current(), Some((&"test", &42)));
653
654 if let Some((key, value)) = cursor.current_mut() {
655 assert_eq!(key, &"test");
656 *value = 100;
657 }
658
659 assert_eq!(cursor.current(), Some((&"test", &100)));
660 assert_eq!(map.get(&"test"), Some(&100));
661 }
662
663 #[test]
664 fn test_cursor_next_and_next_mut() {
665 let mut map = LinkedHashMap::new();
666 map.insert("a", 1);
667 map.insert("b", 2);
668
669 let mut cursor = map.head_cursor_mut();
670 assert_eq!(cursor.next(), Some((&"b", &2)));
671
672 if let Some((key, value)) = cursor.next_mut() {
673 assert_eq!(key, &"b");
674 *value = 20;
675 }
676
677 assert_eq!(cursor.next(), Some((&"b", &20)));
678 assert_eq!(map.get(&"b"), Some(&20));
679 }
680
681 #[test]
682 fn test_cursor_prev_and_prev_mut() {
683 let mut map = LinkedHashMap::new();
684 map.insert("a", 1);
685 map.insert("b", 2);
686
687 let mut cursor = map.tail_cursor_mut();
688 assert_eq!(cursor.prev(), Some((&"a", &1)));
689
690 if let Some((key, value)) = cursor.prev_mut() {
691 assert_eq!(key, &"a");
692 *value = 10;
693 }
694
695 assert_eq!(cursor.prev(), Some((&"a", &10)));
696 assert_eq!(map.get(&"a"), Some(&10));
697 }
698
699 #[test]
700 fn test_cursor_ptr_operations() {
701 let mut map = LinkedHashMap::new();
702 map.insert("a", 1);
703 map.insert("b", 2);
704 map.insert("c", 3);
705
706 let current_ptr;
707 let next_ptr;
708 let prev_ptr;
709 {
710 let cursor = map.head_cursor_mut();
711 current_ptr = cursor.ptr().unwrap();
712 next_ptr = cursor.next_ptr().unwrap();
713 prev_ptr = cursor.prev_ptr().unwrap();
714
715 assert_eq!(cursor.get_ptr(&"b"), Some(next_ptr));
716 assert_eq!(cursor.get_ptr(&"nonexistent"), None);
717 }
718 assert_eq!(map.ptr_get(current_ptr), Some(&1));
719 assert_eq!(map.ptr_get(next_ptr), Some(&2));
720 assert_eq!(map.ptr_get(prev_ptr), Some(&3));
721 }
722
723 #[test]
724 fn test_cursor_at_head_tail_single_element() {
725 let mut map = LinkedHashMap::new();
726 map.insert("only", 1);
727
728 let cursor = map.head_cursor_mut();
729 assert!(cursor.at_head());
730 assert!(cursor.at_tail());
731 assert_eq!(cursor.current(), Some((&"only", &1)));
732 }
733
734 #[test]
735 fn test_cursor_iter_from_position() {
736 let mut map = LinkedHashMap::new();
737 map.insert("a", 1);
738 map.insert("b", 2);
739 map.insert("c", 3);
740 map.insert("d", 4);
741
742 let cursor = map.key_cursor_mut(&"b");
743 let collected: Vec<_> = cursor.iter().map(|(k, v)| (*k, *v)).collect();
744 assert_eq!(collected, vec![("b", 2), ("c", 3), ("d", 4), ("a", 1)]);
745 }
746
747 #[test]
748 fn test_cursor_complex_insertion_sequence() {
749 let mut map = LinkedHashMap::new();
750
751 let mut cursor = map.head_cursor_mut();
752 cursor.insert_after_move_to("b", 2);
753 cursor.insert_before_move_to("a", 1);
754 cursor.insert_after_move_to("c", 3);
755
756 let collected: Vec<_> = map.iter().map(|(k, v)| (*k, *v)).collect();
757 assert_eq!(collected, vec![("a", 1), ("c", 3), ("b", 2)]);
758 }
759
760 #[test]
761 fn test_cursor_mixed_operations() {
762 let mut map = LinkedHashMap::new();
763 map.insert("a", 1);
764 map.insert("b", 2);
765 map.insert("c", 3);
766 map.insert("d", 4);
767
768 {
769 let mut cursor = map.key_cursor_mut(&"b");
770
771 cursor.insert_after_move_to("e", 5);
772 assert_eq!(cursor.current(), Some((&"e", &5)));
773
774 cursor.remove_prev();
775
776 cursor.move_next();
777 let (_ptr, removed) = cursor.remove_next().unwrap();
778 assert_eq!(removed.key, "d");
779 }
780 assert_eq!(map.len(), 3);
781 let final_order: Vec<_> = map.iter().map(|(k, v)| (*k, *v)).collect();
782 assert_eq!(final_order, vec![("a", 1), ("e", 5), ("c", 3)]);
783 }
784
785 #[test]
786 fn test_cursor_boundary_conditions() {
787 let mut map = LinkedHashMap::new();
788 map.insert("a", 1);
789 map.insert("b", 2);
790
791 let mut cursor = map.head_cursor_mut();
792
793 cursor.move_prev();
794 assert!(cursor.at_tail());
795 assert_eq!(cursor.current(), Some((&"b", &2)));
796
797 cursor.move_next();
798 assert!(cursor.at_head());
799 assert_eq!(cursor.current(), Some((&"a", &1)));
800
801 let tail_cursor = map.tail_cursor_mut();
802 assert!(tail_cursor.at_tail());
803 assert_eq!(tail_cursor.current(), Some((&"b", &2)));
804 }
805
806 #[test]
807 fn test_cursor_empty_map_operations() {
808 let mut map: LinkedHashMap<&str, i32> = LinkedHashMap::new();
809 let cursor = map.head_cursor_mut();
810
811 assert!(cursor.current().is_none());
812 assert!(cursor.next().is_none());
813 assert!(cursor.prev().is_none());
814 assert!(cursor.ptr().is_none());
815 assert!(cursor.next_ptr().is_none());
816 assert!(cursor.prev_ptr().is_none());
817 assert!(cursor.at_head());
818 assert!(cursor.at_tail());
819 }
820
821 #[test]
822 fn test_cursor_modification_during_iteration() {
823 let mut map = LinkedHashMap::new();
824 map.insert("a", 1);
825 map.insert("b", 2);
826 map.insert("c", 3);
827
828 let mut cursor = map.head_cursor_mut();
829
830 while let Some((key, value)) = cursor.current_mut() {
831 *value *= 10;
832 if *key == "b" {
833 cursor.insert_after_move_to("x", 99);
834 break;
835 }
836 cursor.move_next();
837 }
838
839 let final_state: Vec<_> = map.iter().map(|(k, v)| (*k, *v)).collect();
840 assert_eq!(final_state, vec![("a", 10), ("b", 20), ("x", 99), ("c", 3)]);
841 }
842
843 #[test]
844 fn test_cursor_position_consistency_after_operations() {
845 let mut map = LinkedHashMap::new();
846 map.insert("a", 1);
847 map.insert("b", 2);
848 map.insert("c", 3);
849
850 {
851 let mut cursor = map.key_cursor_mut(&"b");
852 let original_ptr = cursor.ptr().unwrap();
853
854 cursor.insert_after_move_to("d", 4);
855 let new_ptr = cursor.ptr().unwrap();
856 assert_ne!(original_ptr, new_ptr);
857 assert_eq!(cursor.current(), Some((&"d", &4)));
858
859 cursor.insert_before_move_to("e", 5);
860 assert_eq!(cursor.current(), Some((&"e", &5)));
861 }
862 let final_order: Vec<_> = map.iter().map(|(k, v)| (*k, *v)).collect();
863 assert_eq!(
864 final_order,
865 vec![("a", 1), ("b", 2), ("e", 5), ("d", 4), ("c", 3)]
866 );
867 }
868}