1use std::collections::{HashMap, HashSet};
10
11use slotmap::{DefaultKey, SlotMap};
12
13#[derive(Debug)]
15pub struct MsgTree<K> {
16 arena: SlotMap<DefaultKey, MsgTreeNode<K>>,
17 root: DefaultKey,
18 current: HashMap<K, DefaultKey>, mode: MsgTreeMode,
20}
21
22#[derive(Debug)]
24struct MsgTreeNode<K> {
25 children: HashMap<Vec<u8>, DefaultKey>,
27 parent: Option<DefaultKey>,
29 msgline: Option<Vec<u8>>,
31 keys: HashSet<K>,
33}
34
35impl<K> MsgTreeNode<K> {
36 fn new(parent: Option<DefaultKey>, msgline: Option<Vec<u8>>) -> Self {
37 MsgTreeNode {
38 children: HashMap::new(),
39 parent,
40 msgline,
41 keys: HashSet::new(),
42 }
43 }
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)]
48pub enum MsgTreeMode {
49 Defer = 0,
51 Shift = 1,
53 Trace = 2,
55}
56
57impl<K: Eq + std::hash::Hash + Clone> MsgTree<K> {
58 pub fn new(mode: MsgTreeMode) -> Self {
60 let mut arena: SlotMap<DefaultKey, MsgTreeNode<K>> = SlotMap::new();
61 let root_key = arena.insert(MsgTreeNode::new(None, None));
62 MsgTree {
63 arena,
64 root: root_key,
65 current: HashMap::new(),
66 mode,
67 }
68 }
69
70 #[allow(dead_code)]
72 fn get_node(&self, key: DefaultKey) -> Option<&MsgTreeNode<K>> {
73 self.arena.get(key)
74 }
75
76 #[allow(dead_code)]
78 fn get_node_mut(&mut self, key: DefaultKey) -> Option<&mut MsgTreeNode<K>> {
79 self.arena.get_mut(key)
80 }
81
82 pub fn add(&mut self, key: K, msgline: Vec<u8>) {
84 let current_node = self.current.get(&key).copied().unwrap_or(self.root);
86
87 let should_shift = self.mode >= MsgTreeMode::Shift;
89 let key_to_shift = if should_shift {
90 Some(key.clone())
91 } else {
92 None
93 };
94
95 let new_node = self._append_to_node(current_node, msgline, key_to_shift);
97
98 self.current.insert(key, new_node);
100 }
101
102 fn _append_to_node(
104 &mut self,
105 parent_key: DefaultKey,
106 msgline: Vec<u8>,
107 key_to_shift: Option<K>,
108 ) -> DefaultKey {
109 {
111 let parent_node = self
112 .arena
113 .get_mut(parent_key)
114 .expect("parent node not found");
115 if let Some(&child_key) = parent_node.children.get(&msgline) {
116 if let Some(k) = key_to_shift {
118 self._shift_key(parent_key, child_key, k);
119 }
120 return child_key;
121 }
122 }
123
124 let child_key = self
126 .arena
127 .insert(MsgTreeNode::new(Some(parent_key), Some(msgline.clone())));
128
129 {
131 let parent_node = self
132 .arena
133 .get_mut(parent_key)
134 .expect("parent node not found");
135 parent_node.children.insert(msgline, child_key);
136 }
137
138 if let Some(k) = key_to_shift {
140 self._shift_key(parent_key, child_key, k);
141 }
142
143 child_key
144 }
145
146 fn _shift_key(&mut self, parent_key: DefaultKey, child_key: DefaultKey, key: K) {
148 if let Some(parent_node) = self.arena.get_mut(parent_key) {
149 parent_node.keys.remove(&key);
150 }
151
152 if let Some(child_node) = self.arena.get_mut(child_key) {
153 child_node.keys.insert(key);
154 }
155 }
156
157 fn _update_keys(&mut self) {
159 for (key, node_key) in self.current.iter() {
160 if let Some(node) = self.arena.get_mut(*node_key) {
161 node.keys.insert(key.clone());
162 }
163 }
164 self.mode = MsgTreeMode::Shift;
166 }
167
168 pub fn len(&self) -> usize {
170 self.current.len()
171 }
172
173 pub fn is_empty(&self) -> bool {
175 self.current.is_empty()
176 }
177
178 pub fn clear(&mut self) {
180 self.current.clear();
181 self.arena.clear();
183 self.root = self.arena.insert(MsgTreeNode::new(None, None));
184 }
185
186 pub fn get(&self, key: &K) -> Option<MsgTreeElem<'_, K>> {
188 let node_key = self.current.get(key)?;
189 Some(MsgTreeElem {
190 tree: self,
191 node_key: *node_key,
192 })
193 }
194
195 pub fn keys(&self) -> impl Iterator<Item = &K> {
197 self.current.keys()
198 }
199
200 pub fn walk<'a>(&'a mut self, match_filter: Option<&'a dyn Fn(&K) -> bool>) -> WalkIter<'a, K> {
202 if self.mode == MsgTreeMode::Defer {
204 self._update_keys();
205 }
206
207 WalkIter::new(self, match_filter)
208 }
209
210 pub fn walk_trace<'a>(
212 &'a mut self,
213 match_filter: Option<&'a dyn Fn(&K) -> bool>,
214 ) -> WalkTraceIter<'a, K> {
215 assert_eq!(
216 self.mode,
217 MsgTreeMode::Trace,
218 "walk_trace() is only callable in trace mode"
219 );
220
221 WalkTraceIter::new(self, match_filter)
222 }
223
224 pub fn remove(&mut self, match_filter: &dyn Fn(&K) -> bool) {
226 let keys_to_remove: Vec<K> = self
228 .current
229 .keys()
230 .filter(|k| match_filter(*k))
231 .cloned()
232 .collect();
233
234 for key in &keys_to_remove {
236 if let Some(&node_key) = self.current.get(key) {
237 if let Some(node) = self.arena.get_mut(node_key) {
238 node.keys.remove(key);
239 }
240 }
241 self.current.remove(key);
242 }
243 }
244}
245
246#[derive(Debug)]
248pub struct MsgTreeElem<'a, K> {
249 tree: &'a MsgTree<K>,
250 node_key: DefaultKey,
251}
252
253impl<'a, K> MsgTreeElem<'a, K> {
254 pub fn message(&self) -> Vec<u8> {
256 let mut lines: Vec<&[u8]> = Vec::new();
257 let mut current = Some(self.node_key);
258
259 while let Some(node_key) = current {
260 if let Some(node) = self.tree.arena.get(node_key) {
261 if let Some(ref msgline) = node.msgline {
262 lines.push(msgline.as_slice());
263 }
264 current = node.parent;
265 } else {
266 break;
267 }
268 }
269
270 lines.reverse();
272
273 if lines.is_empty() {
274 Vec::new()
275 } else {
276 let mut result = lines[0].to_vec();
277 for line in &lines[1..] {
278 result.push(b'\n');
279 result.extend_from_slice(line);
280 }
281 result
282 }
283 }
284
285 pub fn lines(&self) -> LinesIter<'_, K> {
287 LinesIter {
288 tree: self.tree,
289 current: Some(self.node_key),
290 }
291 }
292}
293
294pub struct LinesIter<'a, K> {
296 tree: &'a MsgTree<K>,
297 current: Option<DefaultKey>,
298}
299
300impl<'a, K> Iterator for LinesIter<'a, K> {
301 type Item = &'a [u8];
302
303 fn next(&mut self) -> Option<Self::Item> {
304 let node_key = self.current?;
305 if let Some(node) = self.tree.arena.get(node_key) {
306 self.current = node.parent;
307 node.msgline.as_ref().map(|msg| msg.as_slice())
308 } else {
309 None
310 }
311 }
312}
313
314pub struct WalkIter<'a, K> {
316 tree: &'a mut MsgTree<K>,
317 stack: Vec<DefaultKey>,
318 match_filter: Option<&'a dyn Fn(&K) -> bool>,
319}
320
321impl<'a, K> WalkIter<'a, K> {
322 fn new(tree: &'a mut MsgTree<K>, match_filter: Option<&'a dyn Fn(&K) -> bool>) -> Self {
323 let mut stack = Vec::new();
324 if let Some(root_node) = tree.arena.get(tree.root) {
326 let mut children: Vec<DefaultKey> = root_node.children.values().copied().collect();
327 children.reverse();
328 stack.extend(children);
329 }
330 WalkIter {
331 tree,
332 stack,
333 match_filter,
334 }
335 }
336}
337
338impl<'a, K: Clone> Iterator for WalkIter<'a, K> {
339 type Item = (Vec<u8>, Vec<K>);
340
341 fn next(&mut self) -> Option<Self::Item> {
342 while let Some(node_key) = self.stack.pop() {
343 if let Some(node) = self.tree.arena.get(node_key) {
346 let mut children: Vec<DefaultKey> = node.children.values().copied().collect();
347 children.reverse();
348 self.stack.extend(children);
349 }
350
351 if let Some(node) = self.tree.arena.get(node_key) {
353 if !node.keys.is_empty() {
354 let filtered_keys: Vec<K> = if let Some(filter) = &self.match_filter {
356 node.keys.iter().filter(|k| filter(*k)).cloned().collect()
357 } else {
358 node.keys.iter().cloned().collect()
359 };
360
361 if !filtered_keys.is_empty() {
362 let mut lines: Vec<&[u8]> = Vec::new();
364 let mut current = Some(node_key);
365
366 while let Some(nk) = current {
367 if let Some(n) = self.tree.arena.get(nk) {
368 if let Some(ref msgline) = n.msgline {
369 lines.push(msgline.as_slice());
370 }
371 current = n.parent;
372 } else {
373 break;
374 }
375 }
376
377 lines.reverse();
378
379 let result = if lines.is_empty() {
380 Vec::new()
381 } else {
382 let mut result = lines[0].to_vec();
383 for line in &lines[1..] {
384 result.push(b'\n');
385 result.extend_from_slice(line);
386 }
387 result
388 };
389
390 return Some((result, filtered_keys));
391 }
392 }
393 }
394 }
395 None
396 }
397}
398
399pub struct WalkTraceIter<'a, K> {
401 tree: &'a mut MsgTree<K>,
402 stack: Vec<(DefaultKey, usize)>,
403 match_filter: Option<&'a dyn Fn(&K) -> bool>,
404}
405
406impl<'a, K> WalkTraceIter<'a, K> {
407 fn new(tree: &'a mut MsgTree<K>, match_filter: Option<&'a dyn Fn(&K) -> bool>) -> Self {
408 let mut stack = Vec::new();
409 if let Some(root_node) = tree.arena.get(tree.root) {
411 let mut children: Vec<(DefaultKey, usize)> =
412 root_node.children.iter().map(|(_, &k)| (k, 1)).collect();
413 children.reverse();
414 stack.extend(children);
415 }
416 WalkTraceIter {
417 tree,
418 stack,
419 match_filter,
420 }
421 }
422}
423
424impl<'a, K: Clone> Iterator for WalkTraceIter<'a, K> {
425 type Item = (Vec<u8>, Vec<K>, usize, usize);
426
427 fn next(&mut self) -> Option<Self::Item> {
428 while let Some((node_key, depth)) = self.stack.pop() {
429 if let Some(node) = self.tree.arena.get(node_key) {
432 let mut children: Vec<(DefaultKey, usize)> =
433 node.children.iter().map(|(_, &k)| (k, depth + 1)).collect();
434 children.reverse();
435 self.stack.extend(children);
436 }
437
438 if let Some(node) = self.tree.arena.get(node_key) {
440 if !node.keys.is_empty() {
441 let filtered_keys: Vec<K> = if let Some(filter) = &self.match_filter {
443 node.keys.iter().filter(|k| filter(*k)).cloned().collect()
444 } else {
445 node.keys.iter().cloned().collect()
446 };
447
448 if !filtered_keys.is_empty() {
449 let msgline = node.msgline.clone().unwrap_or_default();
451
452 let num_children = node.children.len();
454
455 return Some((msgline, filtered_keys, depth, num_children));
456 }
457 }
458 }
459 }
460 None
461 }
462}
463
464#[cfg(test)]
465mod tests {
466 use super::*;
467
468 #[test]
469 fn test_new_is_empty() {
470 let tree: MsgTree<String> = MsgTree::new(MsgTreeMode::Defer);
471 assert!(tree.is_empty());
472 assert_eq!(tree.len(), 0);
473 }
474
475 #[test]
476 fn test_mode_enum() {
477 assert_eq!(MsgTreeMode::Defer as u8, 0);
478 assert_eq!(MsgTreeMode::Shift as u8, 1);
479 assert_eq!(MsgTreeMode::Trace as u8, 2);
480 }
481
482 #[test]
483 fn test_add_single_key() {
484 let mut tree = MsgTree::new(MsgTreeMode::Defer);
485 tree.add("key1".to_string(), b"message".to_vec());
486 assert_eq!(tree.len(), 1);
487 }
488
489 #[test]
490 fn test_add_multiple_lines_same_key() {
491 let mut tree = MsgTree::new(MsgTreeMode::Defer);
492 tree.add("key1".to_string(), b"message1".to_vec());
493 tree.add("key1".to_string(), b"message2".to_vec());
494 assert_eq!(tree.len(), 1);
495
496 let elem = tree.get(&"key1".to_string()).unwrap();
497 assert_eq!(elem.message(), b"message1\nmessage2");
498 }
499
500 #[test]
501 fn test_add_multiple_keys_same_message() {
502 let mut tree = MsgTree::new(MsgTreeMode::Defer);
503 tree.add("key1".to_string(), b"message".to_vec());
504 tree.add("key2".to_string(), b"message".to_vec());
505 assert_eq!(tree.len(), 2);
506
507 let mut walk_results: Vec<_> = tree.walk(None).collect();
508 assert_eq!(walk_results.len(), 1);
509 let (msg, keys) = walk_results.pop().unwrap();
510 assert_eq!(msg, b"message");
511 assert_eq!(keys.len(), 2);
512 }
513
514 #[test]
515 fn test_walk_with_different_messages() {
516 let mut tree = MsgTree::new(MsgTreeMode::Defer);
517 tree.add("key1".to_string(), b"message0".to_vec());
518 tree.add("key2".to_string(), b"message2".to_vec());
519 tree.add("key3".to_string(), b"message3".to_vec());
520
521 let mut walk_results: Vec<_> = tree.walk(None).collect();
522 assert_eq!(walk_results.len(), 3);
523 }
524
525 #[test]
526 fn test_walk_with_match_filter() {
527 let mut tree: MsgTree<(&str, String)> = MsgTree::new(MsgTreeMode::Shift);
528 tree.add(("item1", "key1".to_string()), b"message0".to_vec());
529 tree.add(("item2", "key2".to_string()), b"message2".to_vec());
530 tree.add(("item3", "key3".to_string()), b"message3".to_vec());
531
532 let walk_results: Vec<_> = tree
533 .walk(Some(&|k: &(&str, String)| k.0 == "item2"))
534 .collect();
535 assert_eq!(walk_results.len(), 1);
536 }
537
538 #[test]
539 fn test_walk_with_mapper() {
540 let mut tree: MsgTree<(&str, String)> = MsgTree::new(MsgTreeMode::Shift);
541 tree.add(("item1", "key1".to_string()), b"message0".to_vec());
542 tree.add(("item2", "key2".to_string()), b"message2".to_vec());
543
544 let walk_results: Vec<_> = tree
545 .walk(Some(&|k: &(&str, String)| k.0.starts_with("item")))
546 .collect();
547 assert_eq!(walk_results.len(), 2);
548 }
549
550 #[test]
551 fn test_get_message() {
552 let mut tree = MsgTree::new(MsgTreeMode::Shift);
553 tree.add("key1".to_string(), b"message1".to_vec());
554 tree.add("key1".to_string(), b"message2".to_vec());
555
556 let elem = tree.get(&"key1".to_string()).unwrap();
557 assert_eq!(elem.message(), b"message1\nmessage2");
558 }
559
560 #[test]
561 fn test_get_nonexistent_key() {
562 let mut tree = MsgTree::new(MsgTreeMode::Shift);
563 tree.add("key1".to_string(), b"message".to_vec());
564
565 let elem = tree.get(&"nonexistent".to_string());
566 assert!(elem.is_none());
567 }
568
569 #[test]
570 fn test_clear() {
571 let mut tree = MsgTree::new(MsgTreeMode::Defer);
572 tree.add("key1".to_string(), b"message".to_vec());
573 tree.add("key2".to_string(), b"message".to_vec());
574
575 tree.clear();
576 assert!(tree.is_empty());
577 assert_eq!(tree.len(), 0);
578 }
579
580 #[test]
581 fn test_mode_defer_to_shift() {
582 let mut tree = MsgTree::new(MsgTreeMode::Defer);
583 tree.add("key1".to_string(), b"message0".to_vec());
584 tree.add("key2".to_string(), b"message1".to_vec());
585
586 assert_eq!(tree.mode, MsgTreeMode::Defer);
587
588 let _results: Vec<_> = tree.walk(None).collect();
590
591 assert_eq!(tree.mode, MsgTreeMode::Shift);
592 }
593
594 #[test]
595 fn test_trace_mode() {
596 let mut tree = MsgTree::new(MsgTreeMode::Trace);
597 tree.add("key1".to_string(), b"message0".to_vec());
598 tree.add("key2".to_string(), b"message2".to_vec());
599 tree.add("key3".to_string(), b"message2".to_vec());
600
601 let walk_results: Vec<_> = tree.walk(None).collect();
603 assert_eq!(walk_results.len(), 2);
604
605 let trace_results: Vec<_> = tree.walk_trace(None).collect();
607 assert_eq!(trace_results.len(), 2);
608 }
609
610 #[test]
611 #[should_panic(expected = "walk_trace() is only callable in trace mode")]
612 fn test_walk_trace_in_shift_mode_panics() {
613 let mut tree = MsgTree::new(MsgTreeMode::Shift);
614 tree.add("key1".to_string(), b"message".to_vec());
615 let _results: Vec<_> = tree.walk_trace(None).collect();
616 }
617
618 #[test]
619 fn test_remove_keys() {
620 let mut tree = MsgTree::new(MsgTreeMode::Shift);
621 tree.add("key1".to_string(), b"message0".to_vec());
622 tree.add("key2".to_string(), b"message0".to_vec());
623 tree.add("key3".to_string(), b"message0".to_vec());
624
625 tree.remove(&|k: &String| k == "key2");
626
627 assert_eq!(tree.len(), 2);
628 assert!(tree.get(&"key2".to_string()).is_none());
629 }
630
631 #[test]
632 fn test_deep_tree() {
633 let mut tree = MsgTree::new(MsgTreeMode::Shift);
634 for i in 0..100 {
635 tree.add("key1".to_string(), format!("line{}", i).as_bytes().to_vec());
636 }
637
638 let elem = tree.get(&"key1".to_string()).unwrap();
639 let msg = elem.message();
640 let lines: Vec<_> = msg.split(|&b| b == b'\n').collect();
641 assert_eq!(lines.len(), 100);
642 }
643
644 #[test]
645 fn test_shared_prefix() {
646 let mut tree = MsgTree::new(MsgTreeMode::Shift);
647
648 tree.add("key1".to_string(), b"prefix".to_vec());
650 tree.add("key1".to_string(), b"common".to_vec());
651 tree.add("key2".to_string(), b"prefix".to_vec());
652 tree.add("key2".to_string(), b"common".to_vec());
653
654 let elem = tree.get(&"key1".to_string()).unwrap();
655 assert_eq!(elem.message(), b"prefix\ncommon");
656
657 let elem = tree.get(&"key2".to_string()).unwrap();
658 assert_eq!(elem.message(), b"prefix\ncommon");
659 }
660
661 #[test]
662 fn test_keys_iterator() {
663 let mut tree = MsgTree::new(MsgTreeMode::Shift);
664 tree.add("key1".to_string(), b"message".to_vec());
665 tree.add("key2".to_string(), b"message".to_vec());
666 tree.add("key3".to_string(), b"message".to_vec());
667
668 let keys: Vec<_> = tree.keys().cloned().collect();
669 assert_eq!(keys.len(), 3);
670 assert!(keys.contains(&"key1".to_string()));
671 assert!(keys.contains(&"key2".to_string()));
672 assert!(keys.contains(&"key3".to_string()));
673 }
674}