1#![allow(rustdoc::redundant_explicit_links)]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![cfg_attr(docsrs, allow(unused_attributes))]
4#![cfg_attr(not(feature = "std"), no_std)]
5
6extern crate alloc;
71#[cfg(any(feature = "std", test))]
72extern crate std;
73
74mod iter;
75pub use iter::*;
76#[cfg(test)]
77mod tests;
78
79use alloc::rc::Rc;
80use alloc::sync::Arc;
81use alloc::vec::Vec;
82use core::marker::PhantomData;
83use core::{
84 cmp::{Ordering, PartialEq},
85 fmt, mem,
86 ptr::{NonNull, null},
87};
88use pointers::Pointer;
89
90pub unsafe trait AvlItem<Tag>: Sized {
176 type Key: Ord;
177
178 fn get_node(&self) -> &mut AvlNode<Self, Tag>;
179
180 #[inline(always)]
181 fn cmp(&self, other: &Self) -> Ordering {
182 self.borrow_key().cmp(other.borrow_key())
183 }
184
185 #[inline(always)]
186 fn cmp_key(&self, key: &Self::Key) -> Ordering {
187 key.cmp(self.borrow_key())
188 }
189
190 fn borrow_key(&self) -> &Self::Key;
191}
192
193#[derive(PartialEq, Debug, Copy, Clone)]
194pub enum AvlDirection {
195 Left = 0,
196 Right = 1,
197}
198
199impl AvlDirection {
200 #[inline(always)]
201 fn reverse(self) -> AvlDirection {
202 match self {
203 AvlDirection::Left => AvlDirection::Right,
204 AvlDirection::Right => AvlDirection::Left,
205 }
206 }
207}
208
209macro_rules! avlchild_to_balance {
210 ( $dir: expr ) => {
211 match $dir {
212 AvlDirection::Left => -1,
213 AvlDirection::Right => 1,
214 }
215 };
216}
217
218macro_rules! as_avlitem {
219 ($P: tt, $Tag: tt, $name: ident) => {
220 <$P::Target as AvlItem<$Tag>>::$name
221 };
222}
223
224pub struct AvlNode<T: AvlItem<Tag>, Tag> {
225 pub left: *const T,
226 pub right: *const T,
227 pub parent: *const T,
228 pub balance: i8,
229 _phan: PhantomData<fn(&Tag)>,
230}
231
232unsafe impl<T: AvlItem<Tag> + Send, Tag> Send for AvlNode<T, Tag> {}
233
234impl<T: AvlItem<Tag>, Tag> AvlNode<T, Tag> {
235 #[inline(always)]
236 pub fn detach(&mut self) {
237 self.left = null();
238 self.right = null();
239 self.parent = null();
240 self.balance = 0;
241 }
242
243 #[inline(always)]
244 fn get_child(&self, dir: AvlDirection) -> *const T {
245 match dir {
246 AvlDirection::Left => self.left,
247 AvlDirection::Right => self.right,
248 }
249 }
250
251 #[inline(always)]
252 fn set_child(&mut self, dir: AvlDirection, child: *const T) {
253 match dir {
254 AvlDirection::Left => self.left = child,
255 AvlDirection::Right => self.right = child,
256 }
257 }
258
259 #[inline(always)]
260 fn get_parent(&self) -> *const T {
261 self.parent
262 }
263
264 #[inline(always)]
266 pub fn swap(&mut self, other: &mut AvlNode<T, Tag>) {
267 mem::swap(&mut self.left, &mut other.left);
268 mem::swap(&mut self.right, &mut other.right);
269 mem::swap(&mut self.parent, &mut other.parent);
270 mem::swap(&mut self.balance, &mut other.balance);
271 }
272}
273
274impl<T: AvlItem<Tag>, Tag> Default for AvlNode<T, Tag> {
275 fn default() -> Self {
276 Self { left: null(), right: null(), parent: null(), balance: 0, _phan: Default::default() }
277 }
278}
279
280#[allow(unused_must_use)]
281impl<T: AvlItem<Tag>, Tag> fmt::Debug for AvlNode<T, Tag> {
282 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
283 write!(f, "(")?;
284
285 if !self.left.is_null() {
286 write!(f, "left: {:p}", self.left)?;
287 } else {
288 write!(f, "left: none ")?;
289 }
290
291 if !self.right.is_null() {
292 write!(f, "right: {:p}", self.right)?;
293 } else {
294 write!(f, "right: none ")?;
295 }
296 write!(f, ")")
297 }
298}
299
300pub type AvlCmpFunc<K, T> = fn(&K, &T) -> Ordering;
301
302pub struct AvlTree<P, Tag>
307where
308 P: Pointer,
309 P::Target: AvlItem<Tag>,
310{
311 root: *const P::Target,
312 count: usize,
313 _phan: PhantomData<fn(P, &Tag)>,
314}
315
316unsafe impl<P, Tag> Send for AvlTree<P, Tag>
317where
318 P: Pointer + Send,
319 P::Target: AvlItem<Tag>,
320{
321}
322
323pub struct AvlSearchResult<'a, P: Pointer> {
335 pub node: *const P::Target,
337 pub direction: Option<AvlDirection>,
339 _phan: PhantomData<&'a P::Target>,
340}
341
342impl<P: Pointer> Default for AvlSearchResult<'_, P> {
343 fn default() -> Self {
344 AvlSearchResult { node: null(), direction: Some(AvlDirection::Left), _phan: PhantomData }
345 }
346}
347
348impl<'a, P: Pointer> AvlSearchResult<'a, P> {
349 #[inline(always)]
351 pub fn get_node_ref(&self) -> Option<&'a P::Target> {
352 if self.is_exact() { unsafe { self.node.as_ref() } } else { None }
353 }
354
355 #[inline(always)]
357 pub fn is_exact(&self) -> bool {
358 self.direction.is_none() && !self.node.is_null()
359 }
360
361 #[inline(always)]
391 pub unsafe fn detach<'b>(&'a self) -> AvlSearchResult<'b, P> {
392 AvlSearchResult { node: self.node, direction: self.direction, _phan: PhantomData }
393 }
394
395 #[inline(always)]
397 pub fn get_nearest(&self) -> Option<&P::Target> {
398 if self.node.is_null() { None } else { unsafe { self.node.as_ref() } }
399 }
400}
401
402impl<'a, T> AvlSearchResult<'a, Arc<T>> {
403 pub fn get_exact(&self) -> Option<Arc<T>> {
405 if self.is_exact() {
406 unsafe {
407 Arc::increment_strong_count(self.node);
408 Some(Arc::from_raw(self.node))
409 }
410 } else {
411 None
412 }
413 }
414}
415
416impl<'a, T> AvlSearchResult<'a, Rc<T>> {
417 pub fn get_exact(&self) -> Option<Rc<T>> {
419 if self.is_exact() {
420 unsafe {
421 Rc::increment_strong_count(self.node);
422 Some(Rc::from_raw(self.node))
423 }
424 } else {
425 None
426 }
427 }
428}
429
430macro_rules! return_end {
431 ($tree: expr, $dir: expr) => {{ if $tree.root.is_null() { null() } else { $tree.bottom_child_ref($tree.root, $dir) } }};
432}
433
434macro_rules! balance_to_child {
435 ($balance: expr) => {
436 match $balance {
437 0 | 1 => AvlDirection::Left,
438 _ => AvlDirection::Right,
439 }
440 };
441}
442
443impl<P, Tag> AvlTree<P, Tag>
444where
445 P: Pointer,
446 P::Target: AvlItem<Tag>,
447{
448 #[inline]
450 pub fn new() -> Self {
451 AvlTree { count: 0, root: null(), _phan: Default::default() }
452 }
453
454 #[inline]
459 pub fn drain(&mut self) -> AvlDrain<'_, P, Tag> {
460 AvlDrain::new(self)
461 }
462
463 #[inline]
464 pub fn is_empty(&self) -> bool {
465 self.count == 0
466 }
467
468 #[inline]
469 pub fn len(&self) -> usize {
470 self.count
471 }
472
473 #[inline]
479 pub fn add(&mut self, node: P) -> bool {
480 if self.count == 0 && self.root.is_null() {
481 self.root = node.into_raw();
482 self.count = 1;
483 return true;
484 }
485
486 let w = self._find(node.as_ref(), as_avlitem!(P, Tag, cmp));
487 if w.direction.is_none() {
488 drop(node);
491 return false;
492 }
493
494 let w_node = w.node;
497 let w_dir = w.direction;
498
499 let w_detached = AvlSearchResult { node: w_node, direction: w_dir, _phan: PhantomData };
500
501 self.insert(node, w_detached);
502 true
503 }
504
505 #[inline]
557 pub fn insert(&mut self, new_data: P, w: AvlSearchResult<'_, P>) {
558 debug_assert!(w.direction.is_some());
559 self._insert(new_data, w.node, w.direction.unwrap());
560 }
561
562 #[allow(clippy::not_unsafe_ptr_arg_deref)]
563 pub fn _insert(
564 &mut self,
565 new_data: P,
566 here: *const P::Target, mut which_child: AvlDirection,
568 ) {
569 let mut new_balance: i8;
570 let new_ptr = new_data.into_raw();
571
572 if here.is_null() {
573 if self.count > 0 {
574 panic!("insert into a tree size {} with empty where.node", self.count);
575 }
576 self.root = new_ptr;
577 self.count += 1;
578 return;
579 }
580
581 let parent = unsafe { &*here };
582 let node = unsafe { (*new_ptr).get_node() };
583 let parent_node = parent.get_node();
584 node.parent = here;
585 parent_node.set_child(which_child, new_ptr);
586 self.count += 1;
587
588 let mut data: *const P::Target = here;
595 loop {
596 let node = unsafe { (*data).get_node() };
597 let old_balance = node.balance;
598 new_balance = old_balance + avlchild_to_balance!(which_child);
599 if new_balance == 0 {
600 node.balance = 0;
601 return;
602 }
603 if old_balance != 0 {
604 self.rotate(data, new_balance);
605 return;
606 }
607 node.balance = new_balance;
608 let parent_ptr = node.get_parent();
609 if parent_ptr.is_null() {
610 return;
611 }
612 which_child = self.parent_direction(data, parent_ptr);
613 data = parent_ptr;
614 }
615 }
616
617 pub unsafe fn insert_here(
632 &mut self, new_data: P, here: AvlSearchResult<P>, direction: AvlDirection,
633 ) {
634 let mut dir_child = direction;
635 assert!(!here.node.is_null());
636 let here_node = here.node;
637 let child = unsafe { (*here_node).get_node().get_child(dir_child) };
638 if !child.is_null() {
639 dir_child = dir_child.reverse();
640 let node = self.bottom_child_ref(child, dir_child);
641 self._insert(new_data, node, dir_child);
642 } else {
643 self._insert(new_data, here_node, dir_child);
644 }
645 }
646
647 #[inline(always)]
649 fn set_child2(
650 &mut self, node: &mut AvlNode<P::Target, Tag>, dir: AvlDirection, child: *const P::Target,
651 parent: *const P::Target,
652 ) {
653 if !child.is_null() {
654 unsafe { (*child).get_node().parent = parent };
655 }
656 node.set_child(dir, child);
657 }
658
659 #[inline(always)]
660 fn parent_direction(&self, data: *const P::Target, parent: *const P::Target) -> AvlDirection {
661 if !parent.is_null() {
662 let parent_node = unsafe { (*parent).get_node() };
663 if parent_node.left == data {
664 return AvlDirection::Left;
665 }
666 if parent_node.right == data {
667 return AvlDirection::Right;
668 }
669 panic!("invalid avl tree, node {:p}, parent {:p}", data, parent);
670 }
671 AvlDirection::Left
673 }
674
675 #[inline(always)]
676 fn parent_direction2(&self, data: *const P::Target) -> AvlDirection {
677 let node = unsafe { (*data).get_node() };
678 let parent = node.get_parent();
679 if !parent.is_null() {
680 return self.parent_direction(data, parent);
681 }
682 AvlDirection::Left
684 }
685
686 #[inline]
687 fn rotate(&mut self, data: *const P::Target, balance: i8) -> bool {
688 let dir = if balance < 0 { AvlDirection::Left } else { AvlDirection::Right };
689 let node = unsafe { (*data).get_node() };
690
691 let parent = node.get_parent();
692 let dir_inverse = dir.reverse();
693 let left_heavy = balance >> 1;
694 let right_heavy = -left_heavy;
695
696 let child = node.get_child(dir);
697 let child_node = unsafe { (*child).get_node() };
698 let mut child_balance = child_node.balance;
699
700 let which_child = self.parent_direction(data, parent);
701
702 if child_balance != right_heavy {
704 child_balance += right_heavy;
705
706 let c_right = child_node.get_child(dir_inverse);
707 self.set_child2(node, dir, c_right, data);
708 node.balance = -child_balance;
710
711 node.parent = child;
712 child_node.set_child(dir_inverse, data);
713 child_node.balance = child_balance;
716 if !parent.is_null() {
717 child_node.parent = parent;
718 unsafe { (*parent).get_node() }.set_child(which_child, child);
719 } else {
720 child_node.parent = null();
721 self.root = child;
722 }
723 return child_balance == 0;
724 }
725 let g_child = child_node.get_child(dir_inverse);
729 let g_child_node = unsafe { (*g_child).get_node() };
730 let g_left = g_child_node.get_child(dir);
731 let g_right = g_child_node.get_child(dir_inverse);
732
733 self.set_child2(node, dir, g_right, data);
734 self.set_child2(child_node, dir_inverse, g_left, child);
735
736 let g_child_balance = g_child_node.balance;
743 if g_child_balance == right_heavy {
744 child_node.balance = left_heavy;
745 } else {
746 child_node.balance = 0;
747 }
748 child_node.parent = g_child;
749 g_child_node.set_child(dir, child);
750
751 if g_child_balance == left_heavy {
752 node.balance = right_heavy;
753 } else {
754 node.balance = 0;
755 }
756 g_child_node.balance = 0;
757
758 node.parent = g_child;
759 g_child_node.set_child(dir_inverse, data);
760
761 if !parent.is_null() {
762 g_child_node.parent = parent;
763 unsafe { (*parent).get_node() }.set_child(which_child, g_child);
764 } else {
765 g_child_node.parent = null();
766 self.root = g_child;
767 }
768 true
769 }
770
771 pub unsafe fn remove(&mut self, del: *const P::Target) {
810 if self.count == 0 {
821 return;
822 }
823 if self.count == 1 && self.root == del {
824 self.root = null();
825 self.count = 0;
826 unsafe { (*del).get_node().detach() };
827 return;
828 }
829 let mut which_child: AvlDirection;
830
831 let del_node = unsafe { (*del).get_node() };
833
834 let node_swap_flag = !del_node.left.is_null() && !del_node.right.is_null();
835
836 if node_swap_flag {
837 let dir: AvlDirection = balance_to_child!(del_node.balance + 1);
838 let child_temp = del_node.get_child(dir);
839
840 let dir_inverse: AvlDirection = dir.reverse();
841 let child = self.bottom_child_ref(child_temp, dir_inverse);
842
843 let dir_child_temp =
846 if child == child_temp { dir } else { self.parent_direction2(child) };
847
848 let parent = del_node.get_parent();
851 let dir_child_del = if !parent.is_null() {
852 self.parent_direction(del, parent)
853 } else {
854 AvlDirection::Left
855 };
856
857 let child_node = unsafe { (*child).get_node() };
858 child_node.swap(del_node);
859
860 if child_node.get_child(dir) == child {
862 child_node.set_child(dir, del);
864 }
865
866 let c_dir = child_node.get_child(dir);
867 if c_dir == del {
868 del_node.parent = child;
869 } else if !c_dir.is_null() {
870 unsafe { (*c_dir).get_node() }.parent = child;
871 }
872
873 let c_inv = child_node.get_child(dir_inverse);
874 if c_inv == del {
875 del_node.parent = child;
876 } else if !c_inv.is_null() {
877 unsafe { (*c_inv).get_node() }.parent = child;
878 }
879
880 let parent = child_node.get_parent();
881 if !parent.is_null() {
882 unsafe { (*parent).get_node() }.set_child(dir_child_del, child);
883 } else {
884 self.root = child;
885 }
886
887 let parent = del_node.get_parent();
890 unsafe { (*parent).get_node() }.set_child(dir_child_temp, del);
891 if !del_node.right.is_null() {
892 which_child = AvlDirection::Right;
893 } else {
894 which_child = AvlDirection::Left;
895 }
896 let child = del_node.get_child(which_child);
897 if !child.is_null() {
898 unsafe { (*child).get_node() }.parent = del;
899 }
900 which_child = dir_child_temp;
901 } else {
902 let parent = del_node.get_parent();
904 if !parent.is_null() {
905 which_child = self.parent_direction(del, parent);
906 } else {
907 which_child = AvlDirection::Left;
908 }
909 }
910
911 let parent: *const P::Target = del_node.get_parent();
914
915 let imm_data: *const P::Target =
916 if !del_node.left.is_null() { del_node.left } else { del_node.right };
917
918 if !imm_data.is_null() {
920 let imm_node = unsafe { (*imm_data).get_node() };
921 imm_node.parent = parent;
922 }
923
924 if !parent.is_null() {
925 assert!(self.count > 0);
926 self.count -= 1;
927
928 let parent_node = unsafe { (*parent).get_node() };
929 parent_node.set_child(which_child, imm_data);
930
931 let mut node_data: *const P::Target = parent;
934 let mut old_balance: i8;
935 let mut new_balance: i8;
936 loop {
937 let node = unsafe { (*node_data).get_node() };
941 old_balance = node.balance;
942 new_balance = old_balance - avlchild_to_balance!(which_child);
943
944 if old_balance == 0 {
948 node.balance = new_balance;
949 break;
950 }
951
952 let parent = node.get_parent();
953 which_child = self.parent_direction(node_data, parent);
954
955 if new_balance == 0 {
961 node.balance = new_balance;
962 } else if !self.rotate(node_data, new_balance) {
963 break;
964 }
965
966 if !parent.is_null() {
967 node_data = parent;
968 continue;
969 }
970 break;
971 }
972 } else if !imm_data.is_null() {
973 debug_assert!(self.count > 0);
974 self.count -= 1;
975 self.root = imm_data;
976 }
977 if self.root.is_null() && self.count > 0 {
978 panic!("AvlTree {} nodes left after remove but tree.root == nil", self.count);
979 }
980 del_node.detach();
981 }
982
983 #[inline]
988 pub fn remove_by_key(&mut self, val: &'_ as_avlitem!(P, Tag, Key)) -> Option<P> {
989 let result = self.find(val);
990 self.remove_with(unsafe { result.detach() })
991 }
992
993 #[inline]
1005 pub fn remove_with(&mut self, result: AvlSearchResult<'_, P>) -> Option<P> {
1006 if result.is_exact() {
1007 unsafe {
1008 let p = result.node;
1009 self.remove(p);
1010 Some(P::from_raw(p))
1011 }
1012 } else {
1013 None
1014 }
1015 }
1016
1017 #[inline]
1022 pub fn find<'a>(&'a self, val: &'_ as_avlitem!(P, Tag, Key)) -> AvlSearchResult<'a, P> {
1023 self._find::<as_avlitem!(P, Tag, Key)>(val, |_val, other| _val.cmp(other.borrow_key()))
1024 }
1025
1026 #[inline]
1027 fn _find<'a, K>(
1028 &'a self, val: &'_ K, cmp_func: AvlCmpFunc<K, P::Target>,
1029 ) -> AvlSearchResult<'a, P> {
1030 if self.root.is_null() {
1031 return AvlSearchResult::default();
1032 }
1033 let mut node_data = self.root;
1034 loop {
1035 let diff = cmp_func(val, unsafe { &*node_data });
1036 match diff {
1037 Ordering::Equal => {
1038 return AvlSearchResult {
1039 node: node_data,
1040 direction: None,
1041 _phan: PhantomData,
1042 };
1043 }
1044 Ordering::Less => {
1045 let node = unsafe { (*node_data).get_node() };
1046 let left = node.get_child(AvlDirection::Left);
1047 if left.is_null() {
1048 return AvlSearchResult {
1049 node: node_data,
1050 direction: Some(AvlDirection::Left),
1051 _phan: PhantomData,
1052 };
1053 }
1054 node_data = left;
1055 }
1056 Ordering::Greater => {
1057 let node = unsafe { (*node_data).get_node() };
1058 let right = node.get_child(AvlDirection::Right);
1059 if right.is_null() {
1060 return AvlSearchResult {
1061 node: node_data,
1062 direction: Some(AvlDirection::Right),
1063 _phan: PhantomData,
1064 };
1065 }
1066 node_data = right;
1067 }
1068 }
1069 }
1070 }
1071
1072 #[inline]
1074 pub fn find_contained<'a>(
1075 &'a self, val: &'_ <P::Target as AvlItem<Tag>>::Key,
1076 ) -> Option<&'a P::Target> {
1077 if self.root.is_null() {
1078 return None;
1079 }
1080 let mut node_data = self.root;
1081 let mut result_node: *const P::Target = null();
1082 loop {
1083 let diff = unsafe { &*node_data }.cmp_key(val);
1084 match diff {
1085 Ordering::Equal => {
1086 let node = unsafe { (*node_data).get_node() };
1087 let left = node.get_child(AvlDirection::Left);
1088 result_node = node_data;
1089 if left.is_null() {
1090 break;
1091 } else {
1092 node_data = left;
1093 }
1094 }
1095 Ordering::Less => {
1096 let node = unsafe { (*node_data).get_node() };
1097 let left = node.get_child(AvlDirection::Left);
1098 if left.is_null() {
1099 break;
1100 }
1101 node_data = left;
1102 }
1103 Ordering::Greater => {
1104 let node = unsafe { (*node_data).get_node() };
1105 let right = node.get_child(AvlDirection::Right);
1106 if right.is_null() {
1107 break;
1108 }
1109 node_data = right;
1110 }
1111 }
1112 }
1113 if result_node.is_null() { None } else { unsafe { result_node.as_ref() } }
1114 }
1115
1116 #[inline]
1118 pub fn find_larger_eq<'a>(
1119 &'a self, val: &'_ <P::Target as AvlItem<Tag>>::Key,
1120 ) -> AvlSearchResult<'a, P> {
1121 if self.root.is_null() {
1122 return AvlSearchResult::default();
1123 }
1124 let mut node_data = self.root;
1125 loop {
1126 let diff = unsafe { &*node_data }.cmp_key(val);
1127 match diff {
1128 Ordering::Equal => {
1129 return AvlSearchResult {
1130 node: node_data,
1131 direction: None,
1132 _phan: PhantomData,
1133 };
1134 }
1135 Ordering::Less => {
1136 return AvlSearchResult {
1137 node: node_data,
1138 direction: None,
1139 _phan: PhantomData,
1140 };
1141 }
1142 Ordering::Greater => {
1143 let right = unsafe { (*node_data).get_node() }.get_child(AvlDirection::Right);
1144 if right.is_null() {
1145 return AvlSearchResult {
1146 node: null(),
1147 direction: None,
1148 _phan: PhantomData,
1149 };
1150 }
1151 node_data = right;
1152 }
1153 }
1154 }
1155 }
1156
1157 #[inline]
1159 pub fn find_nearest<'a, K>(
1160 &'a self, val: &'_ <P::Target as AvlItem<Tag>>::Key,
1161 ) -> AvlSearchResult<'a, P> {
1162 if self.root.is_null() {
1163 return AvlSearchResult::default();
1164 }
1165
1166 let mut node_data = self.root;
1167 let mut nearest_node = null();
1168 loop {
1169 let diff = unsafe { &*node_data }.cmp_key(val);
1170 match diff {
1171 Ordering::Equal => {
1172 return AvlSearchResult {
1173 node: node_data,
1174 direction: None,
1175 _phan: PhantomData,
1176 };
1177 }
1178 Ordering::Less => {
1179 nearest_node = node_data;
1180 let left = unsafe { (*node_data).get_node() }.get_child(AvlDirection::Left);
1181 if left.is_null() {
1182 break;
1183 }
1184 node_data = left;
1185 }
1186 Ordering::Greater => {
1187 let right = unsafe { (*node_data).get_node() }.get_child(AvlDirection::Right);
1188 if right.is_null() {
1189 break;
1190 }
1191 node_data = right;
1192 }
1193 }
1194 }
1195 AvlSearchResult { node: nearest_node, direction: None, _phan: PhantomData }
1196 }
1197
1198 #[inline(always)]
1199 fn bottom_child_ref(&self, mut data: *const P::Target, dir: AvlDirection) -> *const P::Target {
1200 loop {
1201 let child = unsafe { (*data).get_node() }.get_child(dir);
1202 if !child.is_null() {
1203 data = child;
1204 } else {
1205 return data;
1206 }
1207 }
1208 }
1209
1210 #[inline]
1216 pub fn iter(&self) -> AvlIter<'_, P, Tag> {
1217 let first_p = if !self.root.is_null() {
1218 Some(unsafe {
1219 NonNull::new_unchecked(
1220 self.bottom_child_ref(self.root, AvlDirection::Left) as *mut P::Target
1221 )
1222 })
1223 } else {
1224 None
1225 };
1226 AvlIter::new(self, first_p, AvlDirection::Right)
1227 }
1228
1229 #[inline]
1236 pub fn iter_rev(&self) -> AvlIter<'_, P, Tag> {
1237 let last_p = if !self.root.is_null() {
1238 Some(unsafe {
1239 NonNull::new_unchecked(
1240 self.bottom_child_ref(self.root, AvlDirection::Right) as *mut P::Target
1241 )
1242 })
1243 } else {
1244 None
1245 };
1246 AvlIter::new(self, last_p, AvlDirection::Left)
1247 }
1248
1249 #[inline]
1250 pub fn next<'a>(&'a self, data: &'a P::Target) -> Option<&'a P::Target> {
1251 if let Some(p) = self.walk_dir(data.into(), AvlDirection::Right) {
1252 Some(unsafe { p.as_ref() })
1253 } else {
1254 None
1255 }
1256 }
1257
1258 #[inline]
1259 pub fn prev<'a>(&'a self, data: &'a P::Target) -> Option<&'a P::Target> {
1260 if let Some(p) = self.walk_dir(data.into(), AvlDirection::Left) {
1261 Some(unsafe { p.as_ref() })
1262 } else {
1263 None
1264 }
1265 }
1266
1267 #[inline]
1268 fn walk_dir(
1269 &self, mut data_ptr: NonNull<P::Target>, dir: AvlDirection,
1270 ) -> Option<NonNull<P::Target>> {
1271 let dir_inverse = dir.reverse();
1272 let node = unsafe { data_ptr.as_ref().get_node() };
1273 let temp = node.get_child(dir);
1274 if !temp.is_null() {
1275 unsafe {
1276 Some(NonNull::new_unchecked(
1277 self.bottom_child_ref(temp, dir_inverse) as *mut P::Target
1278 ))
1279 }
1280 } else {
1281 let mut parent = node.parent;
1282 if parent.is_null() {
1283 return None;
1284 }
1285 loop {
1286 let pdir = self.parent_direction(data_ptr.as_ptr(), parent);
1287 if pdir == dir_inverse {
1288 return Some(unsafe { NonNull::new_unchecked(parent as *mut P::Target) });
1289 }
1290 let data_ptr_raw = parent as *mut P::Target;
1291 parent = unsafe { (*parent).get_node() }.parent;
1292 if parent.is_null() {
1293 return None;
1294 }
1295 unsafe {
1296 data_ptr = NonNull::new_unchecked(data_ptr_raw);
1297 }
1298 }
1299 }
1300 }
1301
1302 #[inline]
1303 fn validate_node(&self, data: *const P::Target) {
1304 let node = unsafe { (*data).get_node() };
1305 let left = node.left;
1306 if !left.is_null() {
1307 assert!(unsafe { &*left }.cmp(unsafe { &*data }) != Ordering::Greater);
1308 assert_eq!(unsafe { (*left).get_node() }.get_parent(), data);
1309 }
1310 let right = node.right;
1311 if !right.is_null() {
1312 assert!(unsafe { &*right }.cmp(unsafe { &*data }) != Ordering::Less);
1313 assert_eq!(unsafe { (*right).get_node() }.get_parent(), data);
1314 }
1315 }
1316
1317 #[inline]
1318 pub fn first(&self) -> Option<&P::Target> {
1319 unsafe { return_end!(self, AvlDirection::Left).as_ref() }
1320 }
1321
1322 #[inline]
1323 pub fn last(&self) -> Option<&P::Target> {
1324 unsafe { return_end!(self, AvlDirection::Right).as_ref() }
1325 }
1326
1327 #[inline]
1328 pub fn nearest<'a>(
1329 &'a self, current: &AvlSearchResult<'a, P>, direction: AvlDirection,
1330 ) -> AvlSearchResult<'a, P> {
1331 if !current.node.is_null() {
1332 if current.direction.is_some() && current.direction != Some(direction) {
1333 return AvlSearchResult { node: current.node, direction: None, _phan: PhantomData };
1334 }
1335 if let Some(node) = self.walk_dir(
1336 unsafe { NonNull::new_unchecked(current.node as *mut P::Target) },
1337 direction,
1338 ) {
1339 return AvlSearchResult {
1340 node: node.as_ptr(),
1341 direction: None,
1342 _phan: PhantomData,
1343 };
1344 }
1345 }
1346 AvlSearchResult::default()
1347 }
1348
1349 pub fn validate(&self) {
1350 let c = {
1351 #[cfg(feature = "std")]
1352 {
1353 ((self.len() + 10) as f32).log2() as usize
1354 }
1355 #[cfg(not(feature = "std"))]
1356 {
1357 100
1358 }
1359 };
1360 let mut stack: Vec<*const P::Target> = Vec::with_capacity(c);
1361 if self.root.is_null() {
1362 assert_eq!(self.count, 0);
1363 return;
1364 }
1365 let mut data = self.root;
1366 let mut visited = 0;
1367 loop {
1368 if !data.is_null() {
1369 let left = {
1370 let node = unsafe { (*data).get_node() };
1371 node.get_child(AvlDirection::Left)
1372 };
1373 if !left.is_null() {
1374 stack.push(data);
1375 data = left;
1376 continue;
1377 }
1378 visited += 1;
1379 self.validate_node(data);
1380 data = unsafe { (*data).get_node() }.get_child(AvlDirection::Right);
1381 } else if !stack.is_empty() {
1382 let _data = stack.pop().unwrap();
1383 self.validate_node(_data);
1384 visited += 1;
1385 let node = unsafe { (*_data).get_node() };
1386 data = node.get_child(AvlDirection::Right);
1387 } else {
1388 break;
1389 }
1390 }
1391 assert_eq!(visited, self.count);
1392 }
1393}
1394
1395impl<P, Tag> Drop for AvlTree<P, Tag>
1396where
1397 P: Pointer,
1398 P::Target: AvlItem<Tag>,
1399{
1400 fn drop(&mut self) {
1401 if mem::needs_drop::<P>() {
1402 for _ in self.drain() {}
1403 }
1404 }
1405}
1406
1407impl<T, Tag> AvlTree<Arc<T>, Tag>
1408where
1409 T: AvlItem<Tag>,
1410{
1411 pub fn remove_ref(&mut self, node: &Arc<T>) {
1412 let p = Arc::as_ptr(node);
1413 unsafe { self.remove(p) };
1414 unsafe { drop(Arc::from_raw(p)) };
1415 }
1416}
1417
1418impl<T, Tag> AvlTree<Rc<T>, Tag>
1419where
1420 T: AvlItem<Tag>,
1421{
1422 pub fn remove_ref(&mut self, node: &Rc<T>) {
1423 let p = Rc::as_ptr(node);
1424 unsafe { self.remove(p) };
1425 unsafe { drop(Rc::from_raw(p)) };
1426 }
1427}