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 let mut to_visit = vec![id.clone()];
339
340 while let Some(current_id) = to_visit.pop() {
341 if let Some(node) = self.nodes.get(¤t_id) {
342 if !node.metadata.deleted {
343 descendants.push(node);
344 to_visit.extend(node.children.iter().cloned());
345 }
346 }
347 }
348
349 descendants
350 }
351
352 pub fn contains(&self, id: &NodeId) -> bool {
354 self.nodes.contains_key(id)
355 }
356
357 pub fn len(&self) -> usize {
359 self.visible_nodes().len()
360 }
361
362 pub fn is_empty(&self) -> bool {
364 self.len() == 0
365 }
366
367 pub fn clear(&mut self) {
369 self.nodes.clear();
370 }
371}
372
373impl<T: Clone + PartialEq + Eq + Send + Sync> CRDT for AddWinsTree<T> {
374 fn replica_id(&self) -> &ReplicaId {
375 &self.replica
376 }
377}
378
379impl<T: Clone + PartialEq + Eq + Send + Sync> Mergeable for AddWinsTree<T> {
380 type Error = TreeError;
381
382 fn merge(&mut self, other: &Self) -> Result<(), Self::Error> {
383 for (id, node) in &other.nodes {
384 match self.nodes.get(id) {
385 Some(existing) => {
386 if node.metadata.modified_at > existing.metadata.modified_at {
388 self.nodes.insert(id.clone(), node.clone());
389 }
390 }
391 None => {
392 self.nodes.insert(id.clone(), node.clone());
394 }
395 }
396 }
397 Ok(())
398 }
399
400 fn has_conflict(&self, other: &Self) -> bool {
401 for (id, node) in &other.nodes {
402 if let Some(existing) = self.nodes.get(id) {
403 if node.metadata.modified_at == existing.metadata.modified_at
405 && node.metadata.last_modified_by != existing.metadata.last_modified_by
406 {
407 return true;
408 }
409 }
410 }
411 false
412 }
413}
414
415#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
420pub struct RemoveWinsTree<T> {
421 config: TreeConfig,
423 nodes: HashMap<NodeId, TreeNode<T>>,
425 replica: ReplicaId,
427}
428
429impl<T: Clone + PartialEq + Eq + Send + Sync> RemoveWinsTree<T> {
430 pub fn new(replica: ReplicaId) -> Self {
432 Self {
433 config: TreeConfig {
434 strategy: TreeStrategy::RemoveWins,
435 preserve_deleted: false,
436 max_depth: None,
437 max_children: None,
438 },
439 nodes: HashMap::new(),
440 replica,
441 }
442 }
443
444 pub fn with_config(replica: ReplicaId, config: TreeConfig) -> Self {
446 Self {
447 config,
448 nodes: HashMap::new(),
449 replica,
450 }
451 }
452
453 pub fn add_root(&mut self, value: T, timestamp: u64) -> NodeId {
455 let node = TreeNode::new(value, self.replica, timestamp);
456 let id = node.id.clone();
457 self.nodes.insert(id.clone(), node);
458 id
459 }
460
461 pub fn add_child(&mut self, parent_id: &NodeId, value: T, timestamp: u64) -> Result<NodeId, TreeError> {
463 if !self.nodes.contains_key(parent_id) {
464 return Err(TreeError::new("Parent node not found".to_string()));
465 }
466
467 let node = TreeNode::new_child(value, self.replica, timestamp, parent_id.clone());
468 let id = node.id.clone();
469
470 self.nodes.insert(id.clone(), node);
472
473 if let Some(parent) = self.nodes.get_mut(parent_id) {
475 parent.add_child(id.clone());
476 }
477
478 Ok(id)
479 }
480
481 pub fn update(&mut self, id: &NodeId, value: T, timestamp: u64) -> Result<(), TreeError> {
483 if let Some(node) = self.nodes.get_mut(id) {
484 node.value = value;
485 node.mark_modified(self.replica, timestamp);
486 Ok(())
487 } else {
488 Err(TreeError::new("Node not found".to_string()))
489 }
490 }
491
492 pub fn remove(&mut self, id: &NodeId) -> Result<(), TreeError> {
494 let parent_id = self.nodes.get(id).and_then(|node| node.parent.clone());
496
497 if let Some(parent_id) = parent_id {
499 if let Some(parent) = self.nodes.get_mut(&parent_id) {
500 parent.remove_child(id);
501 }
502 }
503
504 if self.nodes.remove(id).is_some() {
506 Ok(())
507 } else {
508 Err(TreeError::new("Node not found".to_string()))
509 }
510 }
511
512 pub fn move_node(&mut self, id: &NodeId, new_parent_id: &NodeId) -> Result<(), TreeError> {
514 if !self.nodes.contains_key(id) || !self.nodes.contains_key(new_parent_id) {
515 return Err(TreeError::new("Node not found".to_string()));
516 }
517
518 let old_parent_id = self.nodes.get(id).and_then(|node| node.parent.clone());
520
521 if let Some(old_parent_id) = old_parent_id {
523 if let Some(old_parent) = self.nodes.get_mut(&old_parent_id) {
524 old_parent.remove_child(id);
525 }
526 }
527
528 if let Some(node) = self.nodes.get_mut(id) {
530 node.parent = Some(new_parent_id.clone());
531 }
532
533 if let Some(new_parent) = self.nodes.get_mut(new_parent_id) {
535 new_parent.add_child(id.clone());
536 }
537
538 Ok(())
539 }
540
541 pub fn get(&self, id: &NodeId) -> Option<&TreeNode<T>> {
543 self.nodes.get(id)
544 }
545
546 pub fn nodes(&self) -> Vec<&TreeNode<T>> {
548 self.nodes.values().collect()
549 }
550
551 pub fn roots(&self) -> Vec<&TreeNode<T>> {
553 self.nodes
554 .values()
555 .filter(|n| n.parent.is_none())
556 .collect()
557 }
558
559 pub fn children(&self, id: &NodeId) -> Vec<&TreeNode<T>> {
561 if let Some(node) = self.nodes.get(id) {
562 node.children
563 .iter()
564 .filter_map(|child_id| self.nodes.get(child_id))
565 .collect()
566 } else {
567 Vec::new()
568 }
569 }
570
571 pub fn descendants(&self, id: &NodeId) -> Vec<&TreeNode<T>> {
573 let mut descendants = Vec::new();
574 let mut to_visit = vec![id.clone()];
575
576 while let Some(current_id) = to_visit.pop() {
577 if let Some(node) = self.nodes.get(¤t_id) {
578 descendants.push(node);
579 to_visit.extend(node.children.iter().cloned());
580 }
581 }
582
583 descendants
584 }
585
586 pub fn contains(&self, id: &NodeId) -> bool {
588 self.nodes.contains_key(id)
589 }
590
591 pub fn len(&self) -> usize {
593 self.nodes.len()
594 }
595
596 pub fn is_empty(&self) -> bool {
598 self.nodes.is_empty()
599 }
600
601 pub fn clear(&mut self) {
603 self.nodes.clear();
604 }
605}
606
607impl<T: Clone + PartialEq + Eq + Send + Sync> CRDT for RemoveWinsTree<T> {
608 fn replica_id(&self) -> &ReplicaId {
609 &self.replica
610 }
611}
612
613impl<T: Clone + PartialEq + Eq + Send + Sync> Mergeable for RemoveWinsTree<T> {
614 type Error = TreeError;
615
616 fn merge(&mut self, other: &Self) -> Result<(), Self::Error> {
617 for (id, node) in &other.nodes {
618 match self.nodes.get(id) {
619 Some(existing) => {
620 if node.metadata.modified_at > existing.metadata.modified_at {
622 self.nodes.insert(id.clone(), node.clone());
623 }
624 }
625 None => {
626 self.nodes.insert(id.clone(), node.clone());
628 }
629 }
630 }
631 Ok(())
632 }
633
634 fn has_conflict(&self, other: &Self) -> bool {
635 for (id, node) in &other.nodes {
636 if let Some(existing) = self.nodes.get(id) {
637 if node.metadata.modified_at == existing.metadata.modified_at
639 && node.metadata.last_modified_by != existing.metadata.last_modified_by
640 {
641 return true;
642 }
643 }
644 }
645 false
646 }
647}
648
649#[cfg(test)]
650mod tests {
651 use super::*;
652 use super::super::ReplicaId;
653 use uuid::Uuid;
654
655 fn create_replica(id: u64) -> ReplicaId {
656 ReplicaId::from(Uuid::from_u64_pair(0, id))
657 }
658
659 #[test]
660 fn test_node_id_creation() {
661 let replica = create_replica(1);
662 let node_id = NodeId::new(replica);
663
664 assert_eq!(node_id.replica, replica);
665 assert_ne!(node_id.id, Uuid::nil());
666 }
667
668 #[test]
669 fn test_tree_node_creation() {
670 let replica = create_replica(1);
671 let timestamp = 1234567890;
672 let node = TreeNode::new("test_value", replica, timestamp);
673
674 assert_eq!(node.value, "test_value");
675 assert_eq!(node.metadata.created_at, timestamp);
676 assert_eq!(node.metadata.modified_at, timestamp);
677 assert_eq!(node.metadata.deleted, false);
678 assert_eq!(node.metadata.last_modified_by, replica);
679 assert!(node.parent.is_none());
680 assert!(node.children.is_empty());
681 }
682
683 #[test]
684 fn test_add_wins_tree_basic_operations() {
685 let replica = create_replica(1);
686 let mut tree = AddWinsTree::new(replica);
687
688 let root_id = tree.add_root("root", 1000);
690 assert_eq!(tree.len(), 1);
691 assert!(tree.contains(&root_id));
692
693 let child_id = tree.add_child(&root_id, "child", 2000).unwrap();
695 assert_eq!(tree.len(), 2);
696 assert!(tree.contains(&child_id));
697
698 let root = tree.get(&root_id).unwrap();
700 assert!(root.children.contains(&child_id));
701
702 let child = tree.get(&child_id).unwrap();
703 assert_eq!(child.parent, Some(root_id));
704 }
705
706 #[test]
707 fn test_remove_wins_tree_basic_operations() {
708 let replica = create_replica(1);
709 let mut tree = RemoveWinsTree::new(replica);
710
711 let root_id = tree.add_root("root", 1000);
713 let child_id = tree.add_child(&root_id, "child", 2000).unwrap();
714
715 assert_eq!(tree.len(), 2);
716
717 tree.remove(&child_id).unwrap();
719 assert_eq!(tree.len(), 1);
720 assert!(!tree.contains(&child_id));
721
722 let root = tree.get(&root_id).unwrap();
724 assert!(root.children.is_empty());
725 }
726
727 #[test]
728 fn test_tree_move_operation() {
729 let replica = create_replica(1);
730 let mut tree = AddWinsTree::new(replica);
731
732 let root_id = tree.add_root("root", 1000);
734 let child1_id = tree.add_child(&root_id, "child1", 2000).unwrap();
735 let child2_id = tree.add_child(&child1_id, "child2", 3000).unwrap();
736
737 tree.move_node(&child2_id, &root_id).unwrap();
739
740 let child2 = tree.get(&child2_id).unwrap();
741 assert_eq!(child2.parent, Some(root_id.clone()));
742
743 let root = tree.get(&root_id).unwrap();
744 assert!(root.children.contains(&child2_id));
745
746 let child1 = tree.get(&child1_id).unwrap();
747 assert!(!child1.children.contains(&child2_id));
748 }
749
750 #[test]
751 fn test_tree_traversal() {
752 let replica = create_replica(1);
753 let mut tree = AddWinsTree::new(replica);
754
755 let root_id = tree.add_root("root", 1000);
757 let child1_id = tree.add_child(&root_id, "child1", 2000).unwrap();
758 let child2_id = tree.add_child(&child1_id, "child2", 3000).unwrap();
759
760 let descendants = tree.descendants(&root_id);
762 assert_eq!(descendants.len(), 2);
763
764 let root_children = tree.children(&root_id);
766 assert_eq!(root_children.len(), 1);
767 assert_eq!(root_children[0].id, child1_id);
768 }
769
770 #[test]
771 fn test_tree_merge() {
772 let replica1 = create_replica(1);
773 let replica2 = create_replica(2);
774
775 let mut tree1 = AddWinsTree::new(replica1);
776 let mut tree2 = AddWinsTree::new(replica2);
777
778 let root1_id = tree1.add_root("root1", 1000);
780 let root2_id = tree2.add_root("root2", 2000);
781
782 tree1.merge(&tree2).unwrap();
784
785 assert_eq!(tree1.len(), 2);
787 assert!(tree1.contains(&root1_id));
788 assert!(tree1.contains(&root2_id));
789 }
790
791 #[test]
792 fn test_tree_configuration() {
793 let replica = create_replica(1);
794 let config = TreeConfig {
795 strategy: TreeStrategy::RemoveWins,
796 preserve_deleted: false,
797 max_depth: Some(5),
798 max_children: Some(10),
799 };
800
801 let tree: AddWinsTree<String> = AddWinsTree::with_config(replica, config);
802 assert_eq!(tree.config.strategy, TreeStrategy::RemoveWins);
803 assert_eq!(tree.config.max_depth, Some(5));
804 assert_eq!(tree.config.max_children, Some(10));
805 }
806}