leptos_sync_core/crdt/tree/
add_wins.rs1use super::super::{CRDT, Mergeable, ReplicaId};
4use super::{config::TreeConfig, error::TreeError, types::{NodeId, TreeNode}};
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7
8#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
13pub struct AddWinsTree<T> {
14 config: TreeConfig,
16 nodes: HashMap<NodeId, TreeNode<T>>,
18 replica: ReplicaId,
20}
21
22impl<T: Clone + PartialEq + Eq + Send + Sync> AddWinsTree<T> {
23 pub fn new(replica: ReplicaId) -> Self {
25 Self {
26 config: TreeConfig::default(),
27 nodes: HashMap::new(),
28 replica,
29 }
30 }
31
32 pub fn with_config(replica: ReplicaId, config: TreeConfig) -> Self {
34 Self {
35 config,
36 nodes: HashMap::new(),
37 replica,
38 }
39 }
40
41 pub fn add_root(&mut self, value: T, timestamp: u64) -> NodeId {
43 let node = TreeNode::new(value, self.replica, timestamp);
44 let id = node.id.clone();
45 self.nodes.insert(id.clone(), node);
46 id
47 }
48
49 pub fn add_child(&mut self, parent_id: &NodeId, value: T, timestamp: u64) -> Result<NodeId, TreeError> {
51 if !self.nodes.contains_key(parent_id) {
52 return Err(TreeError::new("Parent node not found".to_string()));
53 }
54
55 let node = TreeNode::new_child(value, self.replica, timestamp, parent_id.clone());
56 let id = node.id.clone();
57
58 self.nodes.insert(id.clone(), node);
60
61 if let Some(parent) = self.nodes.get_mut(parent_id) {
63 parent.add_child(id.clone());
64 }
65
66 Ok(id)
67 }
68
69 pub fn update(&mut self, id: &NodeId, value: T, timestamp: u64) -> Result<(), TreeError> {
71 if let Some(node) = self.nodes.get_mut(id) {
72 node.value = value;
73 node.mark_modified(self.replica, timestamp);
74 Ok(())
75 } else {
76 Err(TreeError::new("Node not found".to_string()))
77 }
78 }
79
80 pub fn remove(&mut self, id: &NodeId, timestamp: u64) -> Result<(), TreeError> {
82 if let Some(node) = self.nodes.get_mut(id) {
83 node.mark_deleted(self.replica, timestamp);
84 Ok(())
85 } else {
86 Err(TreeError::new("Node not found".to_string()))
87 }
88 }
89
90 pub fn move_node(&mut self, id: &NodeId, new_parent_id: &NodeId) -> Result<(), TreeError> {
92 if !self.nodes.contains_key(id) || !self.nodes.contains_key(new_parent_id) {
93 return Err(TreeError::new("Node not found".to_string()));
94 }
95
96 let old_parent_id = self.nodes.get(id).and_then(|node| node.parent.clone());
98
99 if let Some(old_parent_id) = old_parent_id {
101 if let Some(old_parent) = self.nodes.get_mut(&old_parent_id) {
102 old_parent.remove_child(id);
103 }
104 }
105
106 if let Some(node) = self.nodes.get_mut(id) {
108 node.parent = Some(new_parent_id.clone());
109 }
110
111 if let Some(new_parent) = self.nodes.get_mut(new_parent_id) {
113 new_parent.add_child(id.clone());
114 }
115
116 Ok(())
117 }
118
119 pub fn get(&self, id: &NodeId) -> Option<&TreeNode<T>> {
121 self.nodes.get(id)
122 }
123
124 pub fn visible_nodes(&self) -> Vec<&TreeNode<T>> {
126 self.nodes
127 .values()
128 .filter(|n| !n.metadata.deleted)
129 .collect()
130 }
131
132 pub fn all_nodes(&self) -> Vec<&TreeNode<T>> {
134 self.nodes.values().collect()
135 }
136
137 pub fn roots(&self) -> Vec<&TreeNode<T>> {
139 self.nodes
140 .values()
141 .filter(|n| n.parent.is_none() && !n.metadata.deleted)
142 .collect()
143 }
144
145 pub fn children(&self, id: &NodeId) -> Vec<&TreeNode<T>> {
147 if let Some(node) = self.nodes.get(id) {
148 node.children
149 .iter()
150 .filter_map(|child_id| self.nodes.get(child_id))
151 .filter(|n| !n.metadata.deleted)
152 .collect()
153 } else {
154 Vec::new()
155 }
156 }
157
158 pub fn descendants(&self, id: &NodeId) -> Vec<&TreeNode<T>> {
160 let mut descendants = Vec::new();
161 self.collect_descendants(id, &mut descendants);
162 descendants
163 }
164
165 fn collect_descendants<'a>(&'a self, id: &NodeId, descendants: &mut Vec<&'a TreeNode<T>>) {
166 if let Some(node) = self.nodes.get(id) {
167 if !node.metadata.deleted {
168 for child_id in &node.children {
169 if let Some(child_node) = self.nodes.get(child_id) {
170 if !child_node.metadata.deleted {
171 descendants.push(child_node);
172 self.collect_descendants(child_id, descendants);
173 }
174 }
175 }
176 }
177 }
178 }
179
180 pub fn contains(&self, id: &NodeId) -> bool {
182 self.nodes.contains_key(id)
183 }
184
185 pub fn len(&self) -> usize {
187 self.visible_nodes().len()
188 }
189
190 pub fn is_empty(&self) -> bool {
192 self.len() == 0
193 }
194
195 pub fn clear(&mut self) {
197 self.nodes.clear();
198 }
199
200 pub fn config(&self) -> &TreeConfig {
202 &self.config
203 }
204}
205
206impl<T: Clone + PartialEq + Eq + Send + Sync> CRDT for AddWinsTree<T> {
207 fn replica_id(&self) -> &ReplicaId {
208 &self.replica
209 }
210}
211
212impl<T: Clone + PartialEq + Eq + Send + Sync> Mergeable for AddWinsTree<T> {
213 type Error = TreeError;
214
215 fn merge(&mut self, other: &Self) -> Result<(), Self::Error> {
216 for (id, node) in &other.nodes {
217 match self.nodes.get(id) {
218 Some(existing) => {
219 if node.metadata.modified_at > existing.metadata.modified_at {
221 self.nodes.insert(id.clone(), node.clone());
222 }
223 }
224 None => {
225 self.nodes.insert(id.clone(), node.clone());
227 }
228 }
229 }
230 Ok(())
231 }
232
233 fn has_conflict(&self, other: &Self) -> bool {
234 for (id, node) in &other.nodes {
235 if let Some(existing) = self.nodes.get(id) {
236 if node.metadata.modified_at == existing.metadata.modified_at
238 && node.metadata.last_modified_by != existing.metadata.last_modified_by
239 {
240 return true;
241 }
242 }
243 }
244 false
245 }
246}