1use super::{CRDT, Mergeable, ReplicaId};
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4use std::error::Error;
5use uuid::Uuid;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct TreeError {
10 message: String,
11}
12
13impl TreeError {
14 pub fn new(message: String) -> Self {
15 Self { message }
16 }
17}
18
19impl std::fmt::Display for TreeError {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 write!(f, "TreeError: {}", self.message)
22 }
23}
24
25impl Error for TreeError {}
26
27#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
29pub struct NodeId {
30 pub id: Uuid,
32 pub replica: ReplicaId,
34}
35
36impl NodeId {
37 pub fn new(replica: ReplicaId) -> Self {
39 Self {
40 id: Uuid::new_v4(),
41 replica,
42 }
43 }
44
45 pub fn from_parts(id: Uuid, replica: ReplicaId) -> Self {
47 Self { id, replica }
48 }
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
53pub struct NodeMetadata {
54 pub created_at: u64,
56 pub modified_at: u64,
58 pub deleted: bool,
60 pub last_modified_by: ReplicaId,
62}
63
64impl NodeMetadata {
65 pub fn new(replica: ReplicaId, timestamp: u64) -> Self {
67 Self {
68 created_at: timestamp,
69 modified_at: timestamp,
70 deleted: false,
71 last_modified_by: replica,
72 }
73 }
74
75 pub fn mark_modified(&mut self, replica: ReplicaId, timestamp: u64) {
77 self.modified_at = timestamp;
78 self.last_modified_by = replica;
79 }
80
81 pub fn mark_deleted(&mut self, replica: ReplicaId, timestamp: u64) {
83 self.deleted = true;
84 self.mark_modified(replica, timestamp);
85 }
86}
87
88#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
90pub struct TreeNode<T> {
91 pub id: NodeId,
93 pub value: T,
95 pub metadata: NodeMetadata,
97 pub parent: Option<NodeId>,
99 pub children: Vec<NodeId>,
101}
102
103impl<T> TreeNode<T> {
104 pub fn new(value: T, replica: ReplicaId, timestamp: u64) -> Self {
106 Self {
107 id: NodeId::new(replica),
108 value,
109 metadata: NodeMetadata::new(replica, timestamp),
110 parent: None,
111 children: Vec::new(),
112 }
113 }
114
115 pub fn new_child(value: T, replica: ReplicaId, timestamp: u64, parent: NodeId) -> Self {
117 Self {
118 id: NodeId::new(replica),
119 value,
120 metadata: NodeMetadata::new(replica, timestamp),
121 parent: Some(parent),
122 children: Vec::new(),
123 }
124 }
125
126 pub fn mark_modified(&mut self, replica: ReplicaId, timestamp: u64) {
128 self.metadata.mark_modified(replica, timestamp);
129 }
130
131 pub fn mark_deleted(&mut self, replica: ReplicaId, timestamp: u64) {
133 self.metadata.mark_deleted(replica, timestamp);
134 }
135
136 pub fn add_child(&mut self, child_id: NodeId) {
138 self.children.push(child_id);
139 }
140
141 pub fn remove_child(&mut self, child_id: &NodeId) -> bool {
143 if let Some(pos) = self.children.iter().position(|id| id == child_id) {
144 self.children.remove(pos);
145 true
146 } else {
147 false
148 }
149 }
150}
151
152#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
154pub enum TreeStrategy {
155 AddWins,
157 RemoveWins,
159}
160
161#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
163pub struct TreeConfig {
164 pub strategy: TreeStrategy,
166 pub preserve_deleted: bool,
168 pub max_depth: Option<usize>,
170 pub max_children: Option<usize>,
172}
173
174impl Default for TreeConfig {
175 fn default() -> Self {
176 Self {
177 strategy: TreeStrategy::AddWins,
178 preserve_deleted: true,
179 max_depth: None,
180 max_children: None,
181 }
182 }
183}
184
185#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
190pub struct AddWinsTree<T> {
191 config: TreeConfig,
193 nodes: HashMap<NodeId, TreeNode<T>>,
195 replica: ReplicaId,
197}
198
199impl<T: Clone + PartialEq + Eq + Send + Sync> AddWinsTree<T> {
200 pub fn new(replica: ReplicaId) -> Self {
202 Self {
203 config: TreeConfig::default(),
204 nodes: HashMap::new(),
205 replica,
206 }
207 }
208
209 pub fn with_config(replica: ReplicaId, config: TreeConfig) -> Self {
211 Self {
212 config,
213 nodes: HashMap::new(),
214 replica,
215 }
216 }
217
218 pub fn add_root(&mut self, value: T, timestamp: u64) -> NodeId {
220 let node = TreeNode::new(value, self.replica, timestamp);
221 let id = node.id.clone();
222 self.nodes.insert(id.clone(), node);
223 id
224 }
225
226 pub fn add_child(&mut self, parent_id: &NodeId, value: T, timestamp: u64) -> Result<NodeId, TreeError> {
228 if !self.nodes.contains_key(parent_id) {
229 return Err(TreeError::new("Parent node not found".to_string()));
230 }
231
232 let node = TreeNode::new_child(value, self.replica, timestamp, parent_id.clone());
233 let id = node.id.clone();
234
235 self.nodes.insert(id.clone(), node);
237
238 if let Some(parent) = self.nodes.get_mut(parent_id) {
240 parent.add_child(id.clone());
241 }
242
243 Ok(id)
244 }
245
246 pub fn update(&mut self, id: &NodeId, value: T, timestamp: u64) -> Result<(), TreeError> {
248 if let Some(node) = self.nodes.get_mut(id) {
249 node.value = value;
250 node.mark_modified(self.replica, timestamp);
251 Ok(())
252 } else {
253 Err(TreeError::new("Node not found".to_string()))
254 }
255 }
256
257 pub fn remove(&mut self, id: &NodeId, timestamp: u64) -> Result<(), TreeError> {
259 if let Some(node) = self.nodes.get_mut(id) {
260 node.mark_deleted(self.replica, timestamp);
261 Ok(())
262 } else {
263 Err(TreeError::new("Node not found".to_string()))
264 }
265 }
266
267 pub fn move_node(&mut self, id: &NodeId, new_parent_id: &NodeId) -> Result<(), TreeError> {
269 if !self.nodes.contains_key(id) || !self.nodes.contains_key(new_parent_id) {
270 return Err(TreeError::new("Node not found".to_string()));
271 }
272
273 let old_parent_id = self.nodes.get(id).and_then(|node| node.parent.clone());
275
276 if let Some(old_parent_id) = old_parent_id {
278 if let Some(old_parent) = self.nodes.get_mut(&old_parent_id) {
279 old_parent.remove_child(id);
280 }
281 }
282
283 if let Some(node) = self.nodes.get_mut(id) {
285 node.parent = Some(new_parent_id.clone());
286 }
287
288 if let Some(new_parent) = self.nodes.get_mut(new_parent_id) {
290 new_parent.add_child(id.clone());
291 }
292
293 Ok(())
294 }
295
296 pub fn get(&self, id: &NodeId) -> Option<&TreeNode<T>> {
298 self.nodes.get(id)
299 }
300
301 pub fn visible_nodes(&self) -> Vec<&TreeNode<T>> {
303 self.nodes
304 .values()
305 .filter(|n| !n.metadata.deleted)
306 .collect()
307 }
308
309 pub fn all_nodes(&self) -> Vec<&TreeNode<T>> {
311 self.nodes.values().collect()
312 }
313
314 pub fn roots(&self) -> Vec<&TreeNode<T>> {
316 self.nodes
317 .values()
318 .filter(|n| n.parent.is_none() && !n.metadata.deleted)
319 .collect()
320 }
321
322 pub fn children(&self, id: &NodeId) -> Vec<&TreeNode<T>> {
324 if let Some(node) = self.nodes.get(id) {
325 node.children
326 .iter()
327 .filter_map(|child_id| self.nodes.get(child_id))
328 .filter(|n| !n.metadata.deleted)
329 .collect()
330 } else {
331 Vec::new()
332 }
333 }
334
335 pub fn descendants(&self, id: &NodeId) -> Vec<&TreeNode<T>> {
337 let mut descendants = Vec::new();
338 self.collect_descendants(id, &mut descendants);
339 descendants
340 }
341
342 fn collect_descendants<'a>(&'a self, id: &NodeId, descendants: &mut Vec<&'a TreeNode<T>>) {
343 if let Some(node) = self.nodes.get(id) {
344 if !node.metadata.deleted {
345 for child_id in &node.children {
346 if let Some(child_node) = self.nodes.get(child_id) {
347 if !child_node.metadata.deleted {
348 descendants.push(child_node);
349 self.collect_descendants(child_id, descendants);
350 }
351 }
352 }
353 }
354 }
355 }
356
357 pub fn contains(&self, id: &NodeId) -> bool {
359 self.nodes.contains_key(id)
360 }
361
362 pub fn len(&self) -> usize {
364 self.visible_nodes().len()
365 }
366
367 pub fn is_empty(&self) -> bool {
369 self.len() == 0
370 }
371
372 pub fn clear(&mut self) {
374 self.nodes.clear();
375 }
376}
377
378impl<T: Clone + PartialEq + Eq + Send + Sync> CRDT for AddWinsTree<T> {
379 fn replica_id(&self) -> &ReplicaId {
380 &self.replica
381 }
382}
383
384impl<T: Clone + PartialEq + Eq + Send + Sync> Mergeable for AddWinsTree<T> {
385 type Error = TreeError;
386
387 fn merge(&mut self, other: &Self) -> Result<(), Self::Error> {
388 for (id, node) in &other.nodes {
389 match self.nodes.get(id) {
390 Some(existing) => {
391 if node.metadata.modified_at > existing.metadata.modified_at {
393 self.nodes.insert(id.clone(), node.clone());
394 }
395 }
396 None => {
397 self.nodes.insert(id.clone(), node.clone());
399 }
400 }
401 }
402 Ok(())
403 }
404
405 fn has_conflict(&self, other: &Self) -> bool {
406 for (id, node) in &other.nodes {
407 if let Some(existing) = self.nodes.get(id) {
408 if node.metadata.modified_at == existing.metadata.modified_at
410 && node.metadata.last_modified_by != existing.metadata.last_modified_by
411 {
412 return true;
413 }
414 }
415 }
416 false
417 }
418}
419
420#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
425pub struct RemoveWinsTree<T> {
426 config: TreeConfig,
428 nodes: HashMap<NodeId, TreeNode<T>>,
430 replica: ReplicaId,
432}
433
434impl<T: Clone + PartialEq + Eq + Send + Sync> RemoveWinsTree<T> {
435 pub fn new(replica: ReplicaId) -> Self {
437 Self {
438 config: TreeConfig {
439 strategy: TreeStrategy::RemoveWins,
440 preserve_deleted: false,
441 max_depth: None,
442 max_children: None,
443 },
444 nodes: HashMap::new(),
445 replica,
446 }
447 }
448
449 pub fn with_config(replica: ReplicaId, config: TreeConfig) -> Self {
451 Self {
452 config,
453 nodes: HashMap::new(),
454 replica,
455 }
456 }
457
458 pub fn add_root(&mut self, value: T, timestamp: u64) -> NodeId {
460 let node = TreeNode::new(value, self.replica, timestamp);
461 let id = node.id.clone();
462 self.nodes.insert(id.clone(), node);
463 id
464 }
465
466 pub fn add_child(&mut self, parent_id: &NodeId, value: T, timestamp: u64) -> Result<NodeId, TreeError> {
468 if !self.nodes.contains_key(parent_id) {
469 return Err(TreeError::new("Parent node not found".to_string()));
470 }
471
472 let node = TreeNode::new_child(value, self.replica, timestamp, parent_id.clone());
473 let id = node.id.clone();
474
475 self.nodes.insert(id.clone(), node);
477
478 if let Some(parent) = self.nodes.get_mut(parent_id) {
480 parent.add_child(id.clone());
481 }
482
483 Ok(id)
484 }
485
486 pub fn update(&mut self, id: &NodeId, value: T, timestamp: u64) -> Result<(), TreeError> {
488 if let Some(node) = self.nodes.get_mut(id) {
489 node.value = value;
490 node.mark_modified(self.replica, timestamp);
491 Ok(())
492 } else {
493 Err(TreeError::new("Node not found".to_string()))
494 }
495 }
496
497 pub fn remove(&mut self, id: &NodeId) -> Result<(), TreeError> {
499 let parent_id = self.nodes.get(id).and_then(|node| node.parent.clone());
501
502 if let Some(parent_id) = parent_id {
504 if let Some(parent) = self.nodes.get_mut(&parent_id) {
505 parent.remove_child(id);
506 }
507 }
508
509 if self.nodes.remove(id).is_some() {
511 Ok(())
512 } else {
513 Err(TreeError::new("Node not found".to_string()))
514 }
515 }
516
517 pub fn move_node(&mut self, id: &NodeId, new_parent_id: &NodeId) -> Result<(), TreeError> {
519 if !self.nodes.contains_key(id) || !self.nodes.contains_key(new_parent_id) {
520 return Err(TreeError::new("Node not found".to_string()));
521 }
522
523 let old_parent_id = self.nodes.get(id).and_then(|node| node.parent.clone());
525
526 if let Some(old_parent_id) = old_parent_id {
528 if let Some(old_parent) = self.nodes.get_mut(&old_parent_id) {
529 old_parent.remove_child(id);
530 }
531 }
532
533 if let Some(node) = self.nodes.get_mut(id) {
535 node.parent = Some(new_parent_id.clone());
536 }
537
538 if let Some(new_parent) = self.nodes.get_mut(new_parent_id) {
540 new_parent.add_child(id.clone());
541 }
542
543 Ok(())
544 }
545
546 pub fn get(&self, id: &NodeId) -> Option<&TreeNode<T>> {
548 self.nodes.get(id)
549 }
550
551 pub fn nodes(&self) -> Vec<&TreeNode<T>> {
553 self.nodes.values().collect()
554 }
555
556 pub fn roots(&self) -> Vec<&TreeNode<T>> {
558 self.nodes
559 .values()
560 .filter(|n| n.parent.is_none())
561 .collect()
562 }
563
564 pub fn children(&self, id: &NodeId) -> Vec<&TreeNode<T>> {
566 if let Some(node) = self.nodes.get(id) {
567 node.children
568 .iter()
569 .filter_map(|child_id| self.nodes.get(child_id))
570 .collect()
571 } else {
572 Vec::new()
573 }
574 }
575
576 pub fn descendants(&self, id: &NodeId) -> Vec<&TreeNode<T>> {
578 let mut descendants = Vec::new();
579 self.collect_descendants(id, &mut descendants);
580 descendants
581 }
582
583 fn collect_descendants<'a>(&'a self, id: &NodeId, descendants: &mut Vec<&'a TreeNode<T>>) {
584 if let Some(node) = self.nodes.get(id) {
585 for child_id in &node.children {
586 if let Some(child_node) = self.nodes.get(child_id) {
587 descendants.push(child_node);
588 self.collect_descendants(child_id, descendants);
589 }
590 }
591 }
592 }
593
594 pub fn contains(&self, id: &NodeId) -> bool {
596 self.nodes.contains_key(id)
597 }
598
599 pub fn len(&self) -> usize {
601 self.nodes.len()
602 }
603
604 pub fn is_empty(&self) -> bool {
606 self.nodes.is_empty()
607 }
608
609 pub fn clear(&mut self) {
611 self.nodes.clear();
612 }
613}
614
615impl<T: Clone + PartialEq + Eq + Send + Sync> CRDT for RemoveWinsTree<T> {
616 fn replica_id(&self) -> &ReplicaId {
617 &self.replica
618 }
619}
620
621impl<T: Clone + PartialEq + Eq + Send + Sync> Mergeable for RemoveWinsTree<T> {
622 type Error = TreeError;
623
624 fn merge(&mut self, other: &Self) -> Result<(), Self::Error> {
625 for (id, node) in &other.nodes {
626 match self.nodes.get(id) {
627 Some(existing) => {
628 if node.metadata.modified_at > existing.metadata.modified_at {
630 self.nodes.insert(id.clone(), node.clone());
631 }
632 }
633 None => {
634 self.nodes.insert(id.clone(), node.clone());
636 }
637 }
638 }
639 Ok(())
640 }
641
642 fn has_conflict(&self, other: &Self) -> bool {
643 for (id, node) in &other.nodes {
644 if let Some(existing) = self.nodes.get(id) {
645 if node.metadata.modified_at == existing.metadata.modified_at
647 && node.metadata.last_modified_by != existing.metadata.last_modified_by
648 {
649 return true;
650 }
651 }
652 }
653 false
654 }
655}
656
657#[cfg(test)]
658mod tests {
659 use super::*;
660 use super::super::ReplicaId;
661 use uuid::Uuid;
662
663 fn create_replica(id: u64) -> ReplicaId {
664 ReplicaId::from(Uuid::from_u64_pair(0, id))
665 }
666
667 #[test]
668 fn test_node_id_creation() {
669 let replica = create_replica(1);
670 let node_id = NodeId::new(replica);
671
672 assert_eq!(node_id.replica, replica);
673 assert_ne!(node_id.id, Uuid::nil());
674 }
675
676 #[test]
677 fn test_tree_node_creation() {
678 let replica = create_replica(1);
679 let timestamp = 1234567890;
680 let node = TreeNode::new("test_value", replica, timestamp);
681
682 assert_eq!(node.value, "test_value");
683 assert_eq!(node.metadata.created_at, timestamp);
684 assert_eq!(node.metadata.modified_at, timestamp);
685 assert_eq!(node.metadata.deleted, false);
686 assert_eq!(node.metadata.last_modified_by, replica);
687 assert!(node.parent.is_none());
688 assert!(node.children.is_empty());
689 }
690
691 #[test]
692 fn test_add_wins_tree_basic_operations() {
693 let replica = create_replica(1);
694 let mut tree = AddWinsTree::new(replica);
695
696 let root_id = tree.add_root("root", 1000);
698 assert_eq!(tree.len(), 1);
699 assert!(tree.contains(&root_id));
700
701 let child_id = tree.add_child(&root_id, "child", 2000).unwrap();
703 assert_eq!(tree.len(), 2);
704 assert!(tree.contains(&child_id));
705
706 let root = tree.get(&root_id).unwrap();
708 assert!(root.children.contains(&child_id));
709
710 let child = tree.get(&child_id).unwrap();
711 assert_eq!(child.parent, Some(root_id));
712 }
713
714 #[test]
715 fn test_remove_wins_tree_basic_operations() {
716 let replica = create_replica(1);
717 let mut tree = RemoveWinsTree::new(replica);
718
719 let root_id = tree.add_root("root", 1000);
721 let child_id = tree.add_child(&root_id, "child", 2000).unwrap();
722
723 assert_eq!(tree.len(), 2);
724
725 tree.remove(&child_id).unwrap();
727 assert_eq!(tree.len(), 1);
728 assert!(!tree.contains(&child_id));
729
730 let root = tree.get(&root_id).unwrap();
732 assert!(root.children.is_empty());
733 }
734
735 #[test]
736 fn test_tree_move_operation() {
737 let replica = create_replica(1);
738 let mut tree = AddWinsTree::new(replica);
739
740 let root_id = tree.add_root("root", 1000);
742 let child1_id = tree.add_child(&root_id, "child1", 2000).unwrap();
743 let child2_id = tree.add_child(&child1_id, "child2", 3000).unwrap();
744
745 tree.move_node(&child2_id, &root_id).unwrap();
747
748 let child2 = tree.get(&child2_id).unwrap();
749 assert_eq!(child2.parent, Some(root_id.clone()));
750
751 let root = tree.get(&root_id).unwrap();
752 assert!(root.children.contains(&child2_id));
753
754 let child1 = tree.get(&child1_id).unwrap();
755 assert!(!child1.children.contains(&child2_id));
756 }
757
758 #[test]
759 fn test_tree_traversal() {
760 let replica = create_replica(1);
761 let mut tree = AddWinsTree::new(replica);
762
763 let root_id = tree.add_root("root", 1000);
765 let child1_id = tree.add_child(&root_id, "child1", 2000).unwrap();
766 let child2_id = tree.add_child(&child1_id, "child2", 3000).unwrap();
767
768 let descendants = tree.descendants(&root_id);
770 assert_eq!(descendants.len(), 2);
771
772 let root_children = tree.children(&root_id);
774 assert_eq!(root_children.len(), 1);
775 assert_eq!(root_children[0].id, child1_id);
776 }
777
778 #[test]
779 fn test_tree_merge() {
780 let replica1 = create_replica(1);
781 let replica2 = create_replica(2);
782
783 let mut tree1 = AddWinsTree::new(replica1);
784 let mut tree2 = AddWinsTree::new(replica2);
785
786 let root1_id = tree1.add_root("root1", 1000);
788 let root2_id = tree2.add_root("root2", 2000);
789
790 tree1.merge(&tree2).unwrap();
792
793 assert_eq!(tree1.len(), 2);
795 assert!(tree1.contains(&root1_id));
796 assert!(tree1.contains(&root2_id));
797 }
798
799 #[test]
800 fn test_tree_configuration() {
801 let replica = create_replica(1);
802 let config = TreeConfig {
803 strategy: TreeStrategy::RemoveWins,
804 preserve_deleted: false,
805 max_depth: Some(5),
806 max_children: Some(10),
807 };
808
809 let tree: AddWinsTree<String> = AddWinsTree::with_config(replica, config);
810 assert_eq!(tree.config.strategy, TreeStrategy::RemoveWins);
811 assert_eq!(tree.config.max_depth, Some(5));
812 assert_eq!(tree.config.max_children, Some(10));
813 }
814}