1use std::{borrow::Borrow, fmt, hash::Hash, marker::PhantomData, num::NonZeroUsize, sync::Arc};
5
6use derive_more::{Display, Error};
7
8use crate::{
9 HalfEdge, HalfEdgeOwned, HalfEdgeTreeNode, HashMap, InnerNode, LeafNode, Node, NodeValue,
10 PathSegment, RootPath, SegmentedPath as _,
11};
12
13pub trait NewNodeId<T> {
14 fn new_node_id(&mut self) -> T;
15}
16
17pub trait PathTreeTypes: Clone + Default + fmt::Debug {
19 type NodeId: Clone + Copy + Eq + Hash + fmt::Debug + fmt::Display;
20 type NewNodeId: NewNodeId<Self::NodeId> + Clone + fmt::Debug;
21 type InnerValue: Clone + fmt::Debug;
22 type LeafValue: Clone + fmt::Debug;
23 type PathSegmentOwned: Clone + Eq + Hash + fmt::Debug + Borrow<Self::PathSegment>;
24 type PathSegment: PathSegment + ?Sized;
25 type RootPath: RootPath<Self::PathSegment> + ?Sized;
26
27 fn path_segment_to_owned(path_segment: &Self::PathSegment) -> Self::PathSegmentOwned;
28}
29
30#[derive(Debug)]
32pub struct TreeNodeParentChildPathConflict<T>
33where
34 T: PathTreeTypes,
35{
36 pub parent_node: Arc<TreeNode<T>>,
37 pub child_path_segment: T::PathSegmentOwned,
38}
39
40#[derive(Debug, Display, Error)]
41pub enum InsertOrUpdateNodeValueError<T>
42where
43 T: PathTreeTypes,
44{
45 #[display("path conflict")]
46 PathConflict {
47 conflict: TreeNodeParentChildPathConflict<T>,
48 value: NodeValue<T>,
49 },
50 #[display("value type mismatch")]
51 ValueTypeMismatch { value: NodeValue<T> },
52}
53
54#[derive(Debug, Display, Error)]
55pub enum UpdateNodeValueError<T>
56where
57 T: PathTreeTypes,
58{
59 #[display("value type mismatch")]
60 ValueTypeMismatch { value: NodeValue<T> },
61}
62
63impl<T> From<UpdateNodeValueError<T>> for InsertOrUpdateNodeValueError<T>
64where
65 T: PathTreeTypes,
66{
67 fn from(from: UpdateNodeValueError<T>) -> Self {
68 let UpdateNodeValueError::ValueTypeMismatch { value } = from;
69 Self::ValueTypeMismatch { value }
70 }
71}
72
73#[derive(Debug, Clone)]
74pub struct NodeInsertedOrUpdated<T>
75where
76 T: PathTreeTypes,
77{
78 pub node: Arc<TreeNode<T>>,
82
83 pub parent: Option<ParentNodeUpdated<T>>,
88}
89
90#[derive(Debug, Clone)]
91pub struct ParentNodeUpdated<T>
92where
93 T: PathTreeTypes,
94{
95 pub node: Arc<TreeNode<T>>,
97
98 pub removed_subtree: Option<PathTree<T>>,
100}
101
102#[derive(Debug, Clone)]
104pub struct SubtreeRemoved<T>
105where
106 T: PathTreeTypes,
107{
108 pub parent_node: Arc<TreeNode<T>>,
112
113 pub child_path_segment: T::PathSegmentOwned,
118
119 pub removed_subtree: PathTree<T>,
123}
124
125#[derive(Debug, Clone)]
127pub struct SubtreeInsertedOrReplaced<T>
128where
129 T: PathTreeTypes,
130{
131 pub child_node_id: T::NodeId,
133
134 pub parent: ParentNodeUpdated<T>,
138}
139
140impl<T> InsertOrUpdateNodeValueError<T>
141where
142 T: PathTreeTypes,
143{
144 pub fn into_value(self) -> NodeValue<T> {
145 match self {
146 Self::PathConflict { value, .. } | Self::ValueTypeMismatch { value } => value,
147 }
148 }
149}
150
151#[derive(Debug, Clone)]
155pub struct PathTree<T>
156where
157 T: PathTreeTypes,
158{
159 root_node_id: T::NodeId,
160 nodes: HashMap<T::NodeId, Arc<TreeNode<T>>>,
161 new_node_id: T::NewNodeId,
162 _types: PhantomData<T>,
163}
164
165#[derive(Debug, Default)]
166struct TreeNodeParentChildContext<'a, T>
167where
168 T: PathTreeTypes,
169{
170 parent_node: Option<Arc<TreeNode<T>>>,
171 child_path_segment: Option<&'a T::PathSegment>,
172}
173
174#[derive(Debug, Clone, Copy, PartialEq, Eq)]
175pub enum MatchNodePath {
176 Full,
177 PartialOrFull,
178}
179
180#[derive(Debug, Clone, Copy, PartialEq, Eq)]
181pub enum NodePathMatched {
182 Full {
183 number_of_segments: usize,
187 },
188 Partial {
189 number_of_matched_segments: NonZeroUsize,
193 },
194}
195
196#[derive(Debug, Clone)]
197pub struct NodePathResolved<'a, T>
198where
199 T: PathTreeTypes,
200{
201 pub node: &'a Arc<TreeNode<T>>,
202 pub matched_path: NodePathMatched,
203}
204
205impl<T: PathTreeTypes> PathTree<T> {
206 #[must_use]
208 pub fn new(mut new_node_id: T::NewNodeId, root_node_value: NodeValue<T>) -> Self {
209 let root_node_id = new_node_id.new_node_id();
210 let root_node = TreeNode {
211 id: root_node_id,
212 parent: None,
213 node: Node::from_value_without_children(root_node_value),
214 };
215 let mut nodes = HashMap::new();
216 nodes.insert(root_node_id, Arc::new(root_node));
217 Self {
218 root_node_id,
219 new_node_id,
220 nodes,
221 _types: PhantomData,
222 }
223 }
224
225 fn new_node_id(&mut self) -> T::NodeId {
226 self.new_node_id.new_node_id()
227 }
228
229 #[must_use]
230 pub const fn root_node_id(&self) -> T::NodeId {
231 self.root_node_id
232 }
233
234 #[must_use]
235 pub fn root_node(&self) -> &Arc<TreeNode<T>> {
236 self.get_node(self.root_node_id)
237 }
238
239 #[must_use]
240 pub fn lookup_node(&self, id: T::NodeId) -> Option<&Arc<TreeNode<T>>> {
241 self.nodes.get(&id)
242 }
243
244 #[must_use]
253 fn get_node(&self, id: T::NodeId) -> &Arc<TreeNode<T>> {
254 self.nodes.get(&id).expect("node exists")
255 }
256
257 #[must_use]
259 pub fn find_node(&self, path: &T::RootPath) -> Option<&Arc<TreeNode<T>>> {
260 self.resolve_node_path(path, MatchNodePath::Full).map(
261 |NodePathResolved { node, matched_path }| {
262 debug_assert_eq!(
263 matched_path,
264 NodePathMatched::Full {
265 number_of_segments: path.segments().count()
266 }
267 );
268 node
269 },
270 )
271 }
272
273 #[must_use]
274 pub fn contains_node(&self, node: &Arc<TreeNode<T>>) -> bool {
275 self.lookup_node(node.id)
276 .map_or(false, |tree_node| Arc::ptr_eq(tree_node, node))
277 }
278
279 #[must_use]
283 #[cfg_attr(debug_assertions, allow(clippy::missing_panics_doc))] pub fn resolve_node_path<'a>(
285 &'a self,
286 path: &T::RootPath,
287 match_path: MatchNodePath,
288 ) -> Option<NodePathResolved<'a, T>> {
289 let root_node = self.get_node(self.root_node_id);
291 let mut last_visited_node = root_node;
292 let mut number_of_matched_path_segments = 0;
293 let mut partial_path_match = false;
294 for path_segment in path.segments() {
295 debug_assert!(!path_segment.is_empty());
296 match &last_visited_node.node {
297 Node::Leaf(_) => {
298 match match_path {
300 MatchNodePath::Full => {
301 return None;
302 }
303 MatchNodePath::PartialOrFull => {
304 partial_path_match = true;
305 break;
306 }
307 }
308 }
309 Node::Inner(inner_node) => {
310 let child_node = inner_node
311 .children
312 .get(path_segment)
313 .map(|node_id| self.get_node(*node_id));
314 if let Some(child_node) = child_node {
315 last_visited_node = child_node;
316 number_of_matched_path_segments += 1;
317 } else {
318 match match_path {
320 MatchNodePath::Full => {
321 return None;
322 }
323 MatchNodePath::PartialOrFull => {
324 partial_path_match = true;
325 break;
326 }
327 }
328 }
329 }
330 }
331 debug_assert_eq!(
332 path_segment,
333 last_visited_node
334 .parent
335 .as_ref()
336 .expect("has parent")
337 .path_segment
338 .borrow()
339 );
340 }
341 let matched_path = if partial_path_match {
342 let number_of_matched_segments = NonZeroUsize::new(number_of_matched_path_segments)?;
344 debug_assert!(number_of_matched_segments.get() < path.segments().count());
345 NodePathMatched::Partial {
346 number_of_matched_segments,
347 }
348 } else {
349 debug_assert_eq!(number_of_matched_path_segments, path.segments().count());
350 NodePathMatched::Full {
351 number_of_segments: number_of_matched_path_segments,
352 }
353 };
354 Some(NodePathResolved {
355 node: last_visited_node,
356 matched_path,
357 })
358 }
359
360 #[allow(clippy::too_many_lines)] fn create_missing_ancestor_nodes<'a>(
362 &mut self,
363 child_path: &'a T::RootPath,
364 mut new_inner_value: impl FnMut() -> T::InnerValue,
365 try_clone_leaf_into_inner_value: impl FnOnce(&T::LeafValue) -> Option<T::InnerValue>,
366 ) -> Result<TreeNodeParentChildContext<'a, T>, TreeNodeParentChildPathConflict<T>> {
367 if child_path.is_root() {
368 return Ok(TreeNodeParentChildContext {
369 parent_node: None,
370 child_path_segment: None,
371 });
372 }
373 let mut try_clone_leaf_into_inner_value = Some(try_clone_leaf_into_inner_value);
374 let mut next_parent_node = Arc::clone(self.root_node());
375 let (parent_path_segments, child_path_segment) = child_path.parent_child_segments();
376 debug_assert!(child_path_segment.is_some());
377 for path_segment in parent_path_segments {
378 next_parent_node = match try_replace_leaf_with_inner_node(
379 &mut self.nodes,
380 next_parent_node,
381 &mut try_clone_leaf_into_inner_value,
382 ) {
383 Ok(next_parent_node) => next_parent_node,
384 Err(parent_node) => {
385 return Err(TreeNodeParentChildPathConflict {
386 parent_node,
387 child_path_segment: T::path_segment_to_owned(path_segment),
388 });
389 }
390 };
391 let Node::Inner(inner_node) = &next_parent_node.node else {
392 break;
393 };
394 let child_node = inner_node
395 .children
396 .get(path_segment)
397 .map(|node_id| self.get_node(*node_id));
398 if let Some(child_node) = child_node {
399 log::debug!("Found child node {child_node:?} for path segment {path_segment:?}");
400 next_parent_node = Arc::clone(child_node);
401 } else {
402 let child_node_id = self.new_node_id();
404 debug_assert_ne!(child_node_id, next_parent_node.id);
405 let child_node = TreeNode {
406 id: child_node_id,
407 parent: Some(HalfEdgeOwned {
408 path_segment: T::path_segment_to_owned(path_segment),
409 node_id: next_parent_node.id,
410 }),
411 node: Node::Inner(InnerNode::new(new_inner_value())),
412 };
413 log::debug!(
414 "Inserting new child node {child_node:?} for path segment {path_segment:?}"
415 );
416 let child_node = Arc::new(child_node);
417 let new_next_parent_node = Arc::clone(&child_node);
418 let old_child_node = self.nodes.insert(child_node.id, child_node);
419 debug_assert!(old_child_node.is_none());
420 let mut inner_node = inner_node.clone();
421 let old_child_node_id = inner_node
422 .children
423 .insert(T::path_segment_to_owned(path_segment), child_node_id);
424 debug_assert!(old_child_node_id.is_none());
425 update_parent_node(
427 &mut self.nodes,
428 TreeNode {
429 id: next_parent_node.id,
430 parent: next_parent_node.parent.clone(),
431 node: inner_node.into(),
432 },
433 );
434 next_parent_node = new_next_parent_node;
435 }
436 debug_assert_eq!(
437 path_segment,
438 next_parent_node
439 .parent
440 .as_ref()
441 .expect("has parent")
442 .path_segment
443 .borrow()
444 );
445 }
446 let next_parent_node = match try_replace_leaf_with_inner_node(
447 &mut self.nodes,
448 next_parent_node,
449 &mut try_clone_leaf_into_inner_value,
450 ) {
451 Ok(next_parent_node) => next_parent_node,
452 Err(parent_node) => {
453 return Err(TreeNodeParentChildPathConflict {
454 parent_node,
455 child_path_segment: child_path_segment
456 .map(T::path_segment_to_owned)
457 .expect("child path segment should exist"),
458 });
459 }
460 };
461 let parent_node = match next_parent_node.node {
462 Node::Inner(_) => Some(next_parent_node),
463 Node::Leaf(_) => None,
464 };
465 Ok(TreeNodeParentChildContext {
466 parent_node,
467 child_path_segment,
468 })
469 }
470
471 #[allow(clippy::missing_panics_doc)] pub fn insert_or_update_node_value(
485 &mut self,
486 path: &T::RootPath,
487 new_value: NodeValue<T>,
488 new_inner_value: &mut impl FnMut() -> T::InnerValue,
489 try_clone_leaf_into_inner_value: impl FnOnce(&T::LeafValue) -> Option<T::InnerValue>,
490 ) -> Result<NodeInsertedOrUpdated<T>, InsertOrUpdateNodeValueError<T>> {
491 let TreeNodeParentChildContext {
492 parent_node,
493 child_path_segment,
494 } = match self.create_missing_ancestor_nodes(
495 path,
496 new_inner_value,
497 try_clone_leaf_into_inner_value,
498 ) {
499 Ok(context) => context,
500 Err(conflict) => {
501 return Err(InsertOrUpdateNodeValueError::PathConflict {
502 conflict,
503 value: new_value,
504 });
505 }
506 };
507 let Some(parent_node) = parent_node else {
508 let old_root_node = Arc::clone(self.root_node());
510 let new_root_node = self.update_node_value(&old_root_node, new_value)?;
511 return Ok(NodeInsertedOrUpdated {
512 node: new_root_node,
513 parent: None,
514 });
515 };
516 debug_assert!(matches!(parent_node.node, Node::Inner(_)));
517 let child_path_segment = child_path_segment.expect("should never be empty");
518 self.insert_or_update_child_node_value(&parent_node, child_path_segment, None, new_value)
519 }
520
521 #[allow(clippy::missing_panics_doc)] #[allow(clippy::too_many_lines)] pub fn insert_or_update_child_node_value(
534 &mut self,
535 parent_node: &Arc<TreeNode<T>>,
536 child_path_segment: &T::PathSegment,
537 old_child_path_segment: Option<&T::PathSegment>,
538 new_value: NodeValue<T>,
539 ) -> Result<NodeInsertedOrUpdated<T>, InsertOrUpdateNodeValueError<T>> {
540 debug_assert!(self.contains_node(parent_node));
541 debug_assert!(matches!(parent_node.node, Node::Inner(_)));
542 let Node::Inner(inner_node) = &parent_node.node else {
543 return Err(InsertOrUpdateNodeValueError::PathConflict {
544 conflict: TreeNodeParentChildPathConflict {
545 parent_node: Arc::clone(parent_node),
546 child_path_segment: T::path_segment_to_owned(child_path_segment),
547 },
548 value: new_value,
549 });
550 };
551 let old_child_path_segment = old_child_path_segment.unwrap_or(child_path_segment);
552 let (child_node, inner_node_and_removed_subtree) = if let Some(child_node) = inner_node
553 .children
554 .get(old_child_path_segment)
555 .map(|node_id| self.get_node(*node_id))
556 {
557 let child_node_id = child_node.id;
558 log::debug!("Updating value of existing child node {child_node_id}");
559 let old_child_node = Arc::clone(child_node);
560 if old_child_path_segment == child_path_segment {
561 let new_child_node = self.update_node_value(&old_child_node, new_value)?;
563 (new_child_node, None)
564 } else {
565 let new_parent = HalfEdgeOwned {
566 path_segment: T::path_segment_to_owned(child_path_segment),
567 node_id: parent_node.id,
568 };
569 let updated_child_node =
570 old_child_node.try_clone_with_parent_and_value(Some(new_parent), new_value)?;
571 let (mut inner_node, removed_subtree) = if let Some(subtree_root_node_id) =
572 parent_node.node.find_child(child_path_segment)
573 {
574 log::debug!("Removing child node {child_node_id} with subtree from {child_path_segment:?}");
575 let removed_subtree = self.remove_subtree_by_id(subtree_root_node_id);
576 debug_assert!(removed_subtree.is_some());
577 let SubtreeRemoved {
578 parent_node,
579 child_path_segment: removed_child_path_segment,
580 removed_subtree,
581 } = removed_subtree.expect("subtree has been removed");
582 debug_assert_eq!(removed_child_path_segment.borrow(), child_path_segment);
583 let Node::Inner(inner_node) = &parent_node.node else {
584 unreachable!();
585 };
586 (inner_node.clone(), Some(removed_subtree))
587 } else {
588 (inner_node.clone(), None)
590 };
591 log::debug!("Moving child node {child_node_id} from {old_child_path_segment:?} to {child_path_segment:?}");
593 let removed_child_node_id = inner_node.children.remove(old_child_path_segment);
594 debug_assert_eq!(removed_child_node_id, Some(child_node_id));
595 debug_assert!(self.nodes.contains_key(&child_node_id));
596 let child_node_id = updated_child_node.id;
597 let new_child_node = Arc::new(updated_child_node);
598 let replaced_child_node = self
599 .nodes
600 .insert(child_node_id, Arc::clone(&new_child_node));
601 debug_assert!(replaced_child_node.is_some());
602 debug_assert!(Arc::ptr_eq(
603 replaced_child_node.as_ref().unwrap(),
604 &old_child_node
605 ));
606 debug_assert!(!inner_node.children.contains_key(child_path_segment));
607 inner_node
608 .children
609 .insert(T::path_segment_to_owned(child_path_segment), child_node_id);
610 (new_child_node, Some((inner_node, removed_subtree)))
611 }
612 } else {
613 let child_node_id = self.new_node_id();
614 log::debug!("Adding new child node {child_node_id}");
615 debug_assert!(!self.nodes.contains_key(&child_node_id));
616 let new_child_node = TreeNode {
617 id: child_node_id,
618 parent: Some(HalfEdgeOwned {
619 path_segment: T::path_segment_to_owned(child_path_segment),
620 node_id: parent_node.id,
621 }),
622 node: Node::from_value_without_children(new_value),
623 };
624 let child_node_id = new_child_node.id;
625 let new_child_node = Arc::new(new_child_node);
626 let old_child_node = self
627 .nodes
628 .insert(child_node_id, Arc::clone(&new_child_node));
629 debug_assert!(old_child_node.is_none());
630 log::debug!(
631 "Inserted new child node {new_child_node:?}",
632 new_child_node = *new_child_node,
633 );
634 let mut inner_node = inner_node.clone();
635 if let Some(child_node_id_mut) = inner_node.children.get_mut(child_path_segment) {
636 *child_node_id_mut = child_node_id;
637 } else {
638 inner_node
639 .children
640 .insert(T::path_segment_to_owned(child_path_segment), child_node_id);
641 }
642 (new_child_node, Some((inner_node, None)))
643 };
644 let parent = inner_node_and_removed_subtree.map(|(inner_node, removed_subtree)| {
645 let new_parent_node = update_parent_node(
646 &mut self.nodes,
647 TreeNode {
648 id: parent_node.id,
649 parent: parent_node.parent.clone(),
650 node: Node::Inner(inner_node),
651 },
652 );
653 ParentNodeUpdated {
654 node: new_parent_node,
655 removed_subtree,
656 }
657 });
658 Ok(NodeInsertedOrUpdated {
659 node: child_node,
660 parent,
661 })
662 }
663
664 #[allow(clippy::missing_panics_doc)] pub fn update_node_value(
676 &mut self,
677 node: &Arc<TreeNode<T>>,
678 new_value: NodeValue<T>,
679 ) -> Result<Arc<TreeNode<T>>, UpdateNodeValueError<T>> {
680 debug_assert!(self.contains_node(node));
681 let new_node = Arc::new(node.try_clone_with_value(new_value)?);
682 let old_node = self.nodes.insert(node.id, Arc::clone(&new_node));
683 debug_assert!(old_node.is_some());
684 debug_assert!(old_node.map_or(false, |old_node| Arc::ptr_eq(&old_node, node)));
685 log::debug!("Updated node value: {node:?} -> {new_node:?}");
686 Ok(new_node)
687 }
688
689 #[allow(clippy::missing_panics_doc)] pub fn remove_subtree_by_id(&mut self, node_id: T::NodeId) -> Option<SubtreeRemoved<T>> {
699 if node_id == self.root_node_id {
700 return None;
702 }
703 let nodes_count_before = self.nodes_count();
704 let node = self.nodes.remove(&node_id)?;
705 let descendant_node_ids = node
708 .node
709 .descendants(self)
710 .map(
711 |HalfEdge {
712 path_segment: _,
713 node_id,
714 }| node_id,
715 )
716 .collect::<Vec<_>>();
717 #[cfg(feature = "im")]
719 let mut subtree_nodes: HashMap<_, _> = descendant_node_ids
720 .into_iter()
721 .filter_map(|node_id| self.nodes.remove_with_key(&node_id))
722 .collect();
723 #[cfg(not(feature = "im"))]
724 let mut subtree_nodes: HashMap<_, _> = descendant_node_ids
725 .into_iter()
726 .filter_map(|node_id| self.nodes.remove_entry(&node_id))
727 .collect();
728 let new_parent_node = {
731 debug_assert!(node.parent.is_some());
732 let HalfEdgeOwned {
733 path_segment: parent_path_segment,
734 node_id: parent_node_id,
735 } = node.parent.as_ref().expect("has parent");
736 let parent_node = self.nodes.get(parent_node_id).expect("has a parent");
737 debug_assert!(matches!(parent_node.node, Node::Inner(_)));
738 let Node::Inner(inner_node) = &parent_node.node else {
739 unreachable!();
740 };
741 let mut inner_node = inner_node.clone();
742 let removed_id = inner_node.children.remove(parent_path_segment.borrow());
743 debug_assert_eq!(removed_id, Some(node_id));
744 TreeNode {
745 id: parent_node.id,
746 parent: parent_node.parent.clone(),
747 node: Node::Inner(inner_node),
748 }
749 };
750 let new_parent_node = update_parent_node(&mut self.nodes, new_parent_node);
751 let nodes_count_after = self.nodes_count();
753 debug_assert!(nodes_count_before >= nodes_count_after);
754 let removed_nodes_count = nodes_count_before.get() - nodes_count_after.get();
755 let TreeNode { id, parent, node } = Arc::unwrap_or_clone(node);
756 let parent = parent.expect("has a parent");
757 debug_assert_eq!(parent.node_id, new_parent_node.id);
758 let child_path_segment = parent.path_segment;
759 let subtree_root_node = Arc::new(TreeNode {
760 id,
761 parent: None,
762 node,
763 });
764 subtree_nodes.insert(node_id, subtree_root_node);
765 let removed_subtree = Self {
766 root_node_id: node_id,
767 nodes: subtree_nodes,
768 new_node_id: self.new_node_id.clone(),
769 _types: PhantomData,
770 };
771 debug_assert_eq!(removed_nodes_count, removed_subtree.nodes_count().get());
772 Some(SubtreeRemoved {
773 parent_node: new_parent_node,
774 child_path_segment,
775 removed_subtree,
776 })
777 }
778
779 #[allow(clippy::missing_panics_doc)] pub fn insert_or_replace_subtree(
793 &mut self,
794 parent_node: &Arc<TreeNode<T>>,
795 child_path_segment: &T::PathSegment,
796 old_child_path_segment: Option<&T::PathSegment>,
797 mut subtree: Self,
798 ) -> Result<SubtreeInsertedOrReplaced<T>, InsertOrUpdateNodeValueError<T>> {
799 debug_assert!(self.contains_node(parent_node));
800 let mut subtree_root_node_id = subtree.root_node_id();
803 let mut subtree_root_parent_updated = None;
804 {
805 let subtree_node_ids = std::iter::once(subtree.root_node_id())
806 .chain(subtree.root_node().node.descendants(&subtree).map(
807 |HalfEdge {
808 path_segment: _,
809 node_id,
810 }| node_id,
811 ))
812 .collect::<Vec<_>>();
813 let mut old_to_new_node_id =
814 std::collections::HashMap::<T::NodeId, T::NodeId>::with_capacity(
815 subtree_node_ids.len(),
816 );
817 for old_node_id in subtree_node_ids {
818 let old_node = subtree.nodes.remove(&old_node_id).expect("node exists");
819 let TreeNode {
823 id: _,
824 parent,
825 node,
826 } = Arc::unwrap_or_clone(old_node);
827 let (parent_node, child_path_segment, old_child_path_segment) =
830 if let Some(parent) = parent {
831 debug_assert!(old_to_new_node_id.contains_key(&parent.node_id));
832 let parent_node_id = old_to_new_node_id
833 .get(&parent.node_id)
834 .copied()
835 .expect("parent node has already been inserted");
836 let parent_node = self
837 .nodes
838 .get(&parent_node_id)
839 .expect("parent node has already been inserted");
840 (parent_node, parent.path_segment, None)
841 } else {
842 debug_assert_eq!(old_node_id, subtree.root_node_id());
844 (
845 parent_node,
846 T::path_segment_to_owned(child_path_segment),
847 old_child_path_segment,
848 )
849 };
850 let node_value = match node {
851 Node::Inner(inner) => NodeValue::Inner(inner.value),
852 Node::Leaf(leaf) => NodeValue::Leaf(leaf.value),
853 };
854 let NodeInsertedOrUpdated {
855 node: child_node,
856 parent,
857 } = self
858 .insert_or_update_child_node_value(
859 &Arc::clone(parent_node),
860 child_path_segment.borrow(),
861 old_child_path_segment,
862 node_value,
863 )
864 .inspect_err(|_| {
865 debug_assert_eq!(old_node_id, subtree.root_node_id());
869 })?;
870 let child_node_id = child_node.id;
871 if old_node_id == subtree.root_node_id() {
872 subtree_root_node_id = child_node_id;
874 subtree_root_parent_updated = parent;
875 }
876 debug_assert!(!old_to_new_node_id.contains_key(&old_node_id));
877 old_to_new_node_id.insert(old_node_id, child_node_id);
878 }
879 }
880 Ok(SubtreeInsertedOrReplaced {
881 child_node_id: subtree_root_node_id,
882 parent: subtree_root_parent_updated.expect("parent node has been updated"),
883 })
884 }
885
886 #[allow(clippy::missing_panics_doc)] pub fn retain_nodes(&mut self, mut predicate: impl FnMut(&TreeNode<T>) -> bool) {
893 let mut node_ids_to_remove = Vec::new();
897 for node in self.nodes() {
898 if !predicate(node) && node.id != self.root_node_id() {
899 node_ids_to_remove.push(node.id);
900 }
901 }
902 node_ids_to_remove.sort_by(|lhs_id, rhs_id| {
904 let lhs_node = self.get_node(*lhs_id);
905 let rhs_node = self.get_node(*rhs_id);
906 let lhs_depth = self.ancestor_nodes_count(lhs_node);
907 let rhs_depth = self.ancestor_nodes_count(rhs_node);
908 lhs_depth.cmp(&rhs_depth)
909 });
910 for node_id in node_ids_to_remove {
911 self.remove_subtree_by_id(node_id);
912 }
913 }
914
915 pub fn nodes(&self) -> impl ExactSizeIterator<Item = &Arc<TreeNode<T>>> {
917 self.nodes.values()
918 }
919
920 #[must_use]
926 pub fn nodes_count(&self) -> NonZeroUsize {
927 debug_assert!(!self.nodes.is_empty());
928 let nodes_count = self.nodes.len();
929 #[cfg(feature = "expensive-debug-assertions")]
930 {
931 debug_assert_eq!(
933 nodes_count,
934 1 + self.root_node().node.descendants_count(self)
935 );
936 debug_assert_eq!(nodes_count, self.nodes().count());
937 }
938 debug_assert!(nodes_count > 0);
940 #[allow(unsafe_code)]
941 unsafe {
942 NonZeroUsize::new_unchecked(nodes_count)
943 }
944 }
945
946 pub fn ancestor_nodes<'a>(
951 &'a self,
952 node: &'a Arc<TreeNode<T>>,
953 ) -> impl Iterator<Item = HalfEdgeTreeNode<'_, T>> + Clone {
954 AncestorTreeNodeIter::new(self, node)
955 }
956
957 #[must_use]
959 pub fn ancestor_nodes_count(&self, node: &Arc<TreeNode<T>>) -> usize {
960 self.ancestor_nodes(node).count()
961 }
962
963 pub fn descendant_nodes<'a>(
970 &'a self,
971 node: &'a Arc<TreeNode<T>>,
972 ) -> impl Iterator<Item = HalfEdge<'a, T>> {
973 debug_assert!(self.contains_node(node));
974 node.node.descendants(self)
975 }
976
977 #[must_use]
979 pub fn descendant_nodes_count(&self, node: &Arc<TreeNode<T>>) -> usize {
980 debug_assert!(self.contains_node(node));
981 node.node.descendants_count(self)
982 }
983}
984
985#[derive(Debug, Clone)]
987pub struct TreeNode<T: PathTreeTypes> {
988 pub id: T::NodeId,
990
991 pub parent: Option<HalfEdgeOwned<T>>,
995
996 pub node: Node<T>,
998}
999
1000impl<T: PathTreeTypes> TreeNode<T> {
1001 fn try_clone_with_value(
1002 &self,
1003 new_value: NodeValue<T>,
1004 ) -> Result<Self, UpdateNodeValueError<T>> {
1005 self.try_clone_with_parent_and_value(None, new_value)
1006 }
1007
1008 fn try_clone_with_parent_and_value(
1017 &self,
1018 new_parent: Option<HalfEdgeOwned<T>>,
1019 new_value: NodeValue<T>,
1020 ) -> Result<Self, UpdateNodeValueError<T>> {
1021 let new_node = match &self.node {
1022 Node::Inner(InnerNode { children, .. }) => {
1023 match new_value {
1024 NodeValue::Inner(new_value) => {
1025 Self {
1027 id: self.id,
1028 parent: new_parent.or_else(|| self.parent.clone()),
1029 node: Node::Inner(InnerNode {
1030 children: children.clone(),
1031 value: new_value,
1032 }),
1033 }
1034 }
1035 new_value @ NodeValue::Leaf(_) => {
1036 if !children.is_empty() {
1037 return Err(UpdateNodeValueError::ValueTypeMismatch {
1038 value: new_value,
1039 });
1040 }
1041 Self {
1042 id: self.id,
1043 parent: new_parent.or_else(|| self.parent.clone()),
1044 node: Node::from_value_without_children(new_value),
1045 }
1046 }
1047 }
1048 }
1049 Node::Leaf(_) => {
1050 Self {
1052 id: self.id,
1053 parent: new_parent.or_else(|| self.parent.clone()),
1054 node: Node::from_value_without_children(new_value),
1055 }
1056 }
1057 };
1058 debug_assert_eq!(self.id, new_node.id);
1059 debug_assert_eq!(self.node.children_count(), new_node.node.children_count());
1060 debug_assert!(self
1061 .node
1062 .children()
1063 .zip(new_node.node.children())
1064 .all(|(old, new)| old == new));
1065 Ok(new_node)
1066 }
1067}
1068
1069fn try_replace_leaf_with_inner_node<T: PathTreeTypes>(
1070 nodes: &mut HashMap<T::NodeId, Arc<TreeNode<T>>>,
1071 node: Arc<TreeNode<T>>,
1072 try_clone_leaf_into_inner_value: &mut Option<
1073 impl FnOnce(&T::LeafValue) -> Option<T::InnerValue>,
1074 >,
1075) -> Result<Arc<TreeNode<T>>, Arc<TreeNode<T>>> {
1076 let TreeNode {
1077 id,
1078 parent,
1079 node: Node::Leaf(LeafNode { value: leaf_value }),
1080 } = &*node
1081 else {
1082 return Ok(node);
1083 };
1084 let try_clone_leaf_into_inner_value = try_clone_leaf_into_inner_value
1085 .take()
1086 .expect("consumed at most once");
1087 let Some(inner_value) = try_clone_leaf_into_inner_value(leaf_value) else {
1088 return Err(node);
1090 };
1091 let inner_node = TreeNode {
1093 id: *id,
1094 parent: parent.clone(),
1095 node: InnerNode::new(inner_value).into(),
1096 };
1097 log::debug!(
1098 "Replacing leaf node {leaf_node:?} with inner node {inner_node:?}",
1099 leaf_node = *node
1100 );
1101 let inner_node = Arc::new(inner_node);
1102 let replaced_leaf_node = nodes.insert(inner_node.id, Arc::clone(&inner_node));
1103 debug_assert!(replaced_leaf_node.is_some());
1104 Ok(inner_node)
1105}
1106
1107#[derive(Debug, Clone)]
1111pub struct AncestorTreeNodeIter<'a, T: PathTreeTypes> {
1112 tree: &'a PathTree<T>,
1113 next_node: Option<&'a Arc<TreeNode<T>>>,
1114}
1115
1116impl<'a, T: PathTreeTypes> AncestorTreeNodeIter<'a, T> {
1117 #[must_use]
1122 pub fn new(tree: &'a PathTree<T>, node: &'a Arc<TreeNode<T>>) -> Self {
1123 debug_assert!(tree.contains_node(node));
1124 Self {
1125 tree,
1126 next_node: Some(node),
1127 }
1128 }
1129}
1130
1131impl<'a, T: PathTreeTypes> Iterator for AncestorTreeNodeIter<'a, T> {
1132 type Item = HalfEdgeTreeNode<'a, T>;
1133
1134 fn next(&mut self) -> Option<Self::Item> {
1135 let parent = self.next_node.as_ref()?.parent.as_ref()?;
1136 self.next_node = self.tree.lookup_node(parent.node_id);
1137 self.next_node.map(|node| HalfEdgeTreeNode {
1138 path_segment: parent.path_segment.borrow(),
1139 node,
1140 })
1141 }
1142}
1143
1144fn update_parent_node<T: PathTreeTypes>(
1145 nodes: &mut HashMap<T::NodeId, Arc<TreeNode<T>>>,
1146 parent_node: TreeNode<T>,
1147) -> Arc<TreeNode<T>> {
1148 debug_assert!(matches!(parent_node.node, Node::Inner(_)));
1149 let parent_node_id = parent_node.id;
1150 let new_parent_node = Arc::new(parent_node);
1151 debug_assert!(nodes.contains_key(&parent_node_id));
1152 let old_parent_node = nodes.insert(parent_node_id, Arc::clone(&new_parent_node));
1153 debug_assert!(old_parent_node.is_some());
1154 log::debug!(
1155 "Updated parent node {old_parent_node:?} to {new_parent_node:?}",
1156 old_parent_node = old_parent_node.expect("old parent exists"),
1157 new_parent_node = *new_parent_node,
1158 );
1159 new_parent_node
1160}