1use std::{cmp::Ordering, num::NonZeroU32, ops::Range};
2
3use crate::{Avltriee, AvltrieeAllocator, AvltrieeNode};
4
5pub(crate) type Edge = (Option<NonZeroU32>, Ordering);
6
7pub trait AvltrieeSearch<T, I: ?Sized, A: AvltrieeAllocator<T>>: AsRef<Avltriee<T, I, A>> {
8 fn cmp(left: &I, right: &I) -> Ordering;
9 fn value(&self, row: NonZeroU32) -> Option<&I>;
10 unsafe fn value_unchecked(&self, row: NonZeroU32) -> &I;
11 unsafe fn node_value_unchecked(&self, row: NonZeroU32) -> (&AvltrieeNode<T>, &I);
12
13 fn row(&self, value: &I) -> Option<NonZeroU32> {
15 let edge = self.edge(value);
16 (edge.1 == Ordering::Equal).then(|| edge.0).flatten()
17 }
18
19 fn edge(&self, value: &I) -> Edge {
21 let triee = self.as_ref();
22 let mut row: Option<NonZeroU32> = triee.root();
23 let mut ord = Ordering::Equal;
24 while let Some(row_inner) = row {
25 let (node, node_value) = unsafe { self.node_value_unchecked(row_inner) };
26 ord = Self::cmp(node_value, value);
27 match ord {
28 Ordering::Greater => {
29 if node.left.is_some() {
30 row = node.left;
31 } else {
32 break;
33 }
34 }
35 Ordering::Equal => {
36 break;
37 }
38 Ordering::Less => {
39 if node.right.is_some() {
40 row = node.right;
41 } else {
42 break;
43 }
44 }
45 }
46 }
47 (row, ord)
48 }
49
50 fn ge(&self, value: &I) -> Option<NonZeroU32> {
52 let triee = self.as_ref();
53 let mut row = triee.root();
54 let mut keep = None;
55 while let Some(row_inner) = row {
56 let (node, node_value) = unsafe { self.node_value_unchecked(row_inner) };
57 match Self::cmp(node_value, value) {
58 Ordering::Greater => {
59 if node.left.is_some() {
60 keep = row;
61 row = node.left;
62 } else {
63 return row;
64 }
65 }
66 Ordering::Equal => {
67 return row;
68 }
69 Ordering::Less => {
70 if node.right.is_some() {
71 row = node.right;
72 } else {
73 break;
74 }
75 }
76 }
77 }
78 keep
79 }
80
81 fn le(&self, value: &I) -> Option<NonZeroU32> {
83 let triee = self.as_ref();
84 let mut row = triee.root();
85 let mut keep = None;
86 while let Some(row_inner) = row {
87 let (node, node_value) = unsafe { self.node_value_unchecked(row_inner) };
88 match Self::cmp(node_value, value) {
89 Ordering::Greater => {
90 if node.left.is_some() {
91 row = node.left;
92 } else {
93 break;
94 }
95 }
96 Ordering::Equal => {
97 return row;
98 }
99 Ordering::Less => {
100 if node.right.is_some() {
101 keep = row;
102 row = node.right;
103 } else {
104 return row;
105 }
106 }
107 }
108 }
109 keep
110 }
111
112 fn gt(&self, value: &I) -> Option<NonZeroU32> {
114 let triee = self.as_ref();
115 let mut row = triee.root();
116 let mut keep = None;
117 while let Some(row_inner) = row {
118 let (node, node_value) = unsafe { self.node_value_unchecked(row_inner) };
119 match Self::cmp(node_value, value) {
120 Ordering::Greater => {
121 if node.left.is_some() {
122 keep = row;
123 row = node.left;
124 } else {
125 return row;
126 }
127 }
128 Ordering::Equal => {
129 if node.right.is_some() {
130 return triee.min(node.right);
131 }
132 if let Some(parent) = node.parent {
133 if unsafe { triee.node_unchecked(parent).left } == row {
134 return node.parent;
135 }
136 }
137 break;
138 }
139 Ordering::Less => {
140 if node.right.is_some() {
141 row = node.right;
142 } else {
143 break;
144 }
145 }
146 }
147 }
148 keep
149 }
150
151 fn lt(&self, value: &I) -> Option<NonZeroU32> {
153 let triee = self.as_ref();
154 let mut row = triee.root();
155 let mut keep = None;
156 while let Some(row_inner) = row {
157 let (node, node_value) = unsafe { self.node_value_unchecked(row_inner) };
158 match Self::cmp(node_value, value) {
159 Ordering::Greater => {
160 if node.left.is_some() {
161 row = node.left;
162 } else {
163 break;
164 }
165 }
166 Ordering::Equal => {
167 if node.left.is_some() {
168 return triee.max(node.left);
169 }
170 if let Some(parent) = node.parent {
171 if unsafe { triee.node_unchecked(parent) }.right == row {
172 return node.parent;
173 }
174 }
175 break;
176 }
177 Ordering::Less => {
178 if node.right.is_some() {
179 keep = row;
180 row = node.right;
181 } else {
182 return row;
183 }
184 }
185 }
186 }
187 keep
188 }
189
190 fn range(&self, start_value: &I, end_value: &I) -> Option<Range<NonZeroU32>> {
192 let triee = self.as_ref();
193 let mut row = triee.root();
194 let mut start = None;
195 while let Some(row_inner) = row {
196 let (node, node_value) = unsafe { self.node_value_unchecked(row_inner) };
197 match Self::cmp(node_value, start_value) {
198 Ordering::Greater => {
199 start = row;
200 if node.left.is_some() {
201 row = node.left;
202 } else {
203 break;
204 }
205 }
206 Ordering::Equal => {
207 start = row;
208 break;
209 }
210 Ordering::Less => {
211 if node.right.is_some() {
212 row = node.right;
213 } else {
214 break;
215 }
216 }
217 }
218 }
219 if let Some(start) = start {
220 if Self::cmp(unsafe { self.value_unchecked(start) }, end_value) != Ordering::Greater {
221 row = triee.root();
222 let mut end = None;
223 while let Some(row_inner) = row {
224 let (node, node_value) = unsafe { self.node_value_unchecked(row_inner) };
225 match Self::cmp(node_value, end_value) {
226 Ordering::Greater => {
227 if node.left.is_some() {
228 row = node.left;
229 } else {
230 break;
231 }
232 }
233 Ordering::Equal => {
234 end = row;
235 break;
236 }
237 Ordering::Less => {
238 end = row;
239 if node.right.is_some() {
240 row = node.right;
241 } else {
242 break;
243 }
244 }
245 }
246 }
247 if let Some(end) = end {
248 return Some(Range { start, end });
249 }
250 }
251 }
252 None
253 }
254}