ruvector_graph/optimization/
adaptive_radix.rs1use std::cmp::Ordering;
7use std::mem;
8
9pub struct AdaptiveRadixTree<V: Clone> {
11 root: Option<Box<ArtNode<V>>>,
12 size: usize,
13}
14
15impl<V: Clone> AdaptiveRadixTree<V> {
16 pub fn new() -> Self {
17 Self {
18 root: None,
19 size: 0,
20 }
21 }
22
23 pub fn insert(&mut self, key: &[u8], value: V) {
25 if self.root.is_none() {
26 self.root = Some(Box::new(ArtNode::Leaf {
27 key: key.to_vec(),
28 value,
29 }));
30 self.size += 1;
31 return;
32 }
33
34 let root = self.root.take().unwrap();
35 self.root = Some(Self::insert_recursive(root, key, 0, value));
36 self.size += 1;
37 }
38
39 fn insert_recursive(
40 mut node: Box<ArtNode<V>>,
41 key: &[u8],
42 depth: usize,
43 value: V,
44 ) -> Box<ArtNode<V>> {
45 match node.as_mut() {
46 ArtNode::Leaf {
47 key: leaf_key,
48 value: leaf_value,
49 } => {
50 if *leaf_key == key {
52 *leaf_value = value;
54 return node;
55 }
56
57 let common_prefix_len = Self::common_prefix_len(leaf_key, key, depth);
59 let prefix = if depth + common_prefix_len <= leaf_key.len()
60 && depth + common_prefix_len <= key.len()
61 {
62 key[depth..depth + common_prefix_len].to_vec()
63 } else {
64 vec![]
65 };
66
67 let mut children: [Option<Box<ArtNode<V>>>; 4] = [None, None, None, None];
69 let mut keys_arr = [0u8; 4];
70 let mut num_children = 0u8;
71
72 let next_depth = depth + common_prefix_len;
73
74 let old_byte = if next_depth < leaf_key.len() {
76 Some(leaf_key[next_depth])
77 } else {
78 None
79 };
80
81 let new_byte = if next_depth < key.len() {
82 Some(key[next_depth])
83 } else {
84 None
85 };
86
87 let old_key = std::mem::take(leaf_key);
89 let old_value = unsafe { std::ptr::read(leaf_value) };
90
91 if let Some(byte) = old_byte {
93 keys_arr[num_children as usize] = byte;
94 children[num_children as usize] = Some(Box::new(ArtNode::Leaf {
95 key: old_key,
96 value: old_value,
97 }));
98 num_children += 1;
99 }
100
101 if let Some(byte) = new_byte {
103 let mut insert_idx = num_children as usize;
105 for i in 0..num_children as usize {
106 if byte < keys_arr[i] {
107 insert_idx = i;
108 break;
109 }
110 }
111
112 for i in (insert_idx..num_children as usize).rev() {
114 keys_arr[i + 1] = keys_arr[i];
115 children[i + 1] = children[i].take();
116 }
117
118 keys_arr[insert_idx] = byte;
119 children[insert_idx] = Some(Box::new(ArtNode::Leaf {
120 key: key.to_vec(),
121 value,
122 }));
123 num_children += 1;
124 }
125
126 Box::new(ArtNode::Node4 {
127 prefix,
128 children,
129 keys: keys_arr,
130 num_children,
131 })
132 }
133 ArtNode::Node4 {
134 prefix,
135 children,
136 keys,
137 num_children,
138 } => {
139 let prefix_match = Self::check_prefix(prefix, key, depth);
141
142 if prefix_match < prefix.len() {
143 let common = prefix[..prefix_match].to_vec();
145 let remaining = prefix[prefix_match..].to_vec();
146 let old_byte = remaining[0];
147
148 let old_children = std::mem::replace(children, [None, None, None, None]);
150 let old_keys = *keys;
151 let old_num = *num_children;
152
153 let inner_node = Box::new(ArtNode::Node4 {
154 prefix: remaining[1..].to_vec(),
155 children: old_children,
156 keys: old_keys,
157 num_children: old_num,
158 });
159
160 let next_depth = depth + prefix_match;
162 let new_byte = if next_depth < key.len() {
163 key[next_depth]
164 } else {
165 0
166 };
167 let new_leaf = Box::new(ArtNode::Leaf {
168 key: key.to_vec(),
169 value,
170 });
171
172 let mut new_children: [Option<Box<ArtNode<V>>>; 4] = [None, None, None, None];
174 let mut new_keys = [0u8; 4];
175
176 if old_byte < new_byte {
177 new_keys[0] = old_byte;
178 new_children[0] = Some(inner_node);
179 new_keys[1] = new_byte;
180 new_children[1] = Some(new_leaf);
181 } else {
182 new_keys[0] = new_byte;
183 new_children[0] = Some(new_leaf);
184 new_keys[1] = old_byte;
185 new_children[1] = Some(inner_node);
186 }
187
188 return Box::new(ArtNode::Node4 {
189 prefix: common,
190 children: new_children,
191 keys: new_keys,
192 num_children: 2,
193 });
194 }
195
196 let next_depth = depth + prefix.len();
198 if next_depth < key.len() {
199 let key_byte = key[next_depth];
200
201 for i in 0..(*num_children as usize) {
203 if keys[i] == key_byte {
204 let child = children[i].take().unwrap();
205 children[i] =
206 Some(Self::insert_recursive(child, key, next_depth + 1, value));
207 return node;
208 }
209 }
210
211 if (*num_children as usize) < 4 {
213 let idx = *num_children as usize;
214 keys[idx] = key_byte;
215 children[idx] = Some(Box::new(ArtNode::Leaf {
216 key: key.to_vec(),
217 value,
218 }));
219 *num_children += 1;
220 }
221 }
223
224 node
225 }
226 _ => {
227 node
229 }
230 }
231 }
232
233 pub fn get(&self, key: &[u8]) -> Option<&V> {
235 let mut current = self.root.as_ref()?;
236 let mut depth = 0;
237
238 loop {
239 match current.as_ref() {
240 ArtNode::Leaf {
241 key: leaf_key,
242 value,
243 } => {
244 if leaf_key == key {
245 return Some(value);
246 } else {
247 return None;
248 }
249 }
250 ArtNode::Node4 {
251 prefix,
252 children,
253 keys,
254 num_children,
255 } => {
256 if !Self::match_prefix(prefix, key, depth) {
257 return None;
258 }
259
260 depth += prefix.len();
261 if depth >= key.len() {
262 return None;
263 }
264
265 let key_byte = key[depth];
266 let mut found = false;
267
268 for i in 0..*num_children as usize {
269 if keys[i] == key_byte {
270 current = children[i].as_ref()?;
271 depth += 1;
272 found = true;
273 break;
274 }
275 }
276
277 if !found {
278 return None;
279 }
280 }
281 _ => return None,
282 }
283 }
284 }
285
286 pub fn contains_key(&self, key: &[u8]) -> bool {
288 self.get(key).is_some()
289 }
290
291 pub fn len(&self) -> usize {
293 self.size
294 }
295
296 pub fn is_empty(&self) -> bool {
298 self.size == 0
299 }
300
301 fn common_prefix_len(a: &[u8], b: &[u8], start: usize) -> usize {
303 let mut len = 0;
304 let max = a.len().min(b.len()) - start;
305
306 for i in 0..max {
307 if a[start + i] == b[start + i] {
308 len += 1;
309 } else {
310 break;
311 }
312 }
313
314 len
315 }
316
317 fn check_prefix(prefix: &[u8], key: &[u8], depth: usize) -> usize {
319 let max = prefix.len().min(key.len() - depth);
320 let mut matched = 0;
321
322 for i in 0..max {
323 if prefix[i] == key[depth + i] {
324 matched += 1;
325 } else {
326 break;
327 }
328 }
329
330 matched
331 }
332
333 fn match_prefix(prefix: &[u8], key: &[u8], depth: usize) -> bool {
335 if depth + prefix.len() > key.len() {
336 return false;
337 }
338
339 for i in 0..prefix.len() {
340 if prefix[i] != key[depth + i] {
341 return false;
342 }
343 }
344
345 true
346 }
347}
348
349impl<V: Clone> Default for AdaptiveRadixTree<V> {
350 fn default() -> Self {
351 Self::new()
352 }
353}
354
355pub enum ArtNode<V> {
357 Leaf { key: Vec<u8>, value: V },
359
360 Node4 {
362 prefix: Vec<u8>,
363 children: [Option<Box<ArtNode<V>>>; 4],
364 keys: [u8; 4],
365 num_children: u8,
366 },
367
368 Node16 {
370 prefix: Vec<u8>,
371 children: [Option<Box<ArtNode<V>>>; 16],
372 keys: [u8; 16],
373 num_children: u8,
374 },
375
376 Node48 {
378 prefix: Vec<u8>,
379 children: [Option<Box<ArtNode<V>>>; 48],
380 index: [u8; 256], num_children: u8,
382 },
383
384 Node256 {
386 prefix: Vec<u8>,
387 children: [Option<Box<ArtNode<V>>>; 256],
388 num_children: u16,
389 },
390}
391
392impl<V> ArtNode<V> {
393 pub fn is_leaf(&self) -> bool {
395 matches!(self, ArtNode::Leaf { .. })
396 }
397
398 pub fn node_type(&self) -> &str {
400 match self {
401 ArtNode::Leaf { .. } => "Leaf",
402 ArtNode::Node4 { .. } => "Node4",
403 ArtNode::Node16 { .. } => "Node16",
404 ArtNode::Node48 { .. } => "Node48",
405 ArtNode::Node256 { .. } => "Node256",
406 }
407 }
408}
409
410pub struct ArtIter<'a, V> {
412 stack: Vec<&'a ArtNode<V>>,
413}
414
415impl<'a, V> Iterator for ArtIter<'a, V> {
416 type Item = (&'a [u8], &'a V);
417
418 fn next(&mut self) -> Option<Self::Item> {
419 while let Some(node) = self.stack.pop() {
420 match node {
421 ArtNode::Leaf { key, value } => {
422 return Some((key.as_slice(), value));
423 }
424 ArtNode::Node4 {
425 children,
426 num_children,
427 ..
428 } => {
429 for i in (0..*num_children as usize).rev() {
430 if let Some(child) = &children[i] {
431 self.stack.push(child);
432 }
433 }
434 }
435 _ => {
436 }
438 }
439 }
440 None
441 }
442}
443
444#[cfg(test)]
445mod tests {
446 use super::*;
447
448 #[test]
449 fn test_art_basic() {
450 let mut tree = AdaptiveRadixTree::new();
451
452 tree.insert(b"hello", 1);
453 tree.insert(b"world", 2);
454 tree.insert(b"help", 3);
455
456 assert_eq!(tree.get(b"hello"), Some(&1));
457 assert_eq!(tree.get(b"world"), Some(&2));
458 assert_eq!(tree.get(b"help"), Some(&3));
459 assert_eq!(tree.get(b"nonexistent"), None);
460 }
461
462 #[test]
463 fn test_art_contains() {
464 let mut tree = AdaptiveRadixTree::new();
465
466 tree.insert(b"test", 42);
467
468 assert!(tree.contains_key(b"test"));
469 assert!(!tree.contains_key(b"other"));
470 }
471
472 #[test]
473 fn test_art_len() {
474 let mut tree = AdaptiveRadixTree::new();
475
476 assert_eq!(tree.len(), 0);
477 assert!(tree.is_empty());
478
479 tree.insert(b"a", 1);
480 tree.insert(b"b", 2);
481
482 assert_eq!(tree.len(), 2);
483 assert!(!tree.is_empty());
484 }
485
486 #[test]
487 fn test_art_common_prefix() {
488 let mut tree = AdaptiveRadixTree::new();
489
490 tree.insert(b"prefix_one", 1);
491 tree.insert(b"prefix_two", 2);
492 tree.insert(b"other", 3);
493
494 assert_eq!(tree.get(b"prefix_one"), Some(&1));
495 assert_eq!(tree.get(b"prefix_two"), Some(&2));
496 assert_eq!(tree.get(b"other"), Some(&3));
497 }
498}