1mod balance;
2mod delete;
3
4use std::{cmp::Ordering, num::NonZeroU32};
5
6use crate::{search::Edge, AvltrieeAllocator, AvltrieeSearch};
7
8use super::{Avltriee, AvltrieeNode};
9
10pub trait AvltrieeUpdate<T, I: ?Sized, A: AvltrieeAllocator<T>>:
11 AsMut<Avltriee<T, I, A>> + AvltrieeSearch<T, I, A>
12{
13 fn convert_on_insert_unique(&mut self, input: &I) -> T;
14 fn on_delete(&mut self, _row: NonZeroU32) {}
15
16 fn insert(&mut self, value: &I) -> NonZeroU32
18 where
19 T: Clone,
20 {
21 let row = unsafe { NonZeroU32::new_unchecked(self.as_ref().rows_count() + 1) };
22 self.update(row, value);
23 row
24 }
25
26 fn update(&mut self, row: NonZeroU32, value: &I)
28 where
29 T: Clone,
30 {
31 if let Some(node_value) = self.value(row) {
32 if Self::cmp(node_value, value) == Ordering::Equal {
33 return; }
35 self.delete(row);
36 }
37
38 let edge = self.edge(value);
39 if let (Some(same_row), Ordering::Equal) = edge {
40 let triee = self.as_mut();
41
42 triee.allocate(row);
43
44 let same_node = unsafe { triee.node_unchecked_mut(same_row) };
45 let same_left = same_node.left;
46 let same_right = same_node.right;
47 let same_parent = same_node.parent;
48
49 *unsafe { triee.node_unchecked_mut(row) } = same_node.same_clone(same_row, row);
50
51 triee.replace_child(same_parent, same_row, Some(row));
52
53 if let Some(left) = same_left {
54 unsafe { triee.node_unchecked_mut(left) }.parent = Some(row);
55 }
56 if let Some(right) = same_right {
57 unsafe { triee.node_unchecked_mut(right) }.parent = Some(row);
58 }
59 } else {
60 let value = self.convert_on_insert_unique(value);
61 unsafe { self.as_mut().insert_unique_unchecked(row, value, edge) };
62 }
63 }
64
65 fn delete(&mut self, row: NonZeroU32) {
67 self.on_delete(row);
68 self.as_mut().delete_inner(row);
69 }
70}
71
72impl<T, I: ?Sized, A: AvltrieeAllocator<T>> Avltriee<T, I, A> {
73 pub unsafe fn insert_unique_unchecked(&mut self, row: NonZeroU32, value: T, edge: Edge) {
78 self.allocate(row);
79
80 *self.node_unchecked_mut(row) = AvltrieeNode::new(edge.0, value);
81 if let Some(found_row) = edge.0 {
82 let p = self.node_unchecked_mut(found_row);
83 if edge.1 == Ordering::Greater {
84 p.left = Some(row);
85 } else {
86 p.right = Some(row);
87 }
88 self.balance(row);
89 } else {
90 self.set_root(Some(row));
91 }
92 }
93
94 fn reset_height(&mut self, row: NonZeroU32) {
95 let node = unsafe { self.node_unchecked(row) };
96
97 let left_height = node.left.map_or(
98 0,
99 |left: NonZeroU32| unsafe { self.node_unchecked(left) }.height,
100 );
101
102 let right_height = node
103 .right
104 .map_or(0, |right| unsafe { self.node_unchecked(right) }.height);
105
106 unsafe { self.node_unchecked_mut(row) }.height =
107 std::cmp::max(left_height, right_height) + 1;
108 }
109
110 fn replace_child(
111 &mut self,
112 parent: Option<NonZeroU32>,
113 current_child: NonZeroU32,
114 new_child: Option<NonZeroU32>,
115 ) {
116 if let Some(parent) = parent {
117 unsafe { self.node_unchecked_mut(parent) }.changeling(current_child, new_child);
118 } else {
119 self.set_root(new_child);
120 }
121 }
122}