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