leptos_sync_core/crdt/graph/
mod.rs

1//! Graph CRDT implementations
2//!
3//! This module provides graph-based CRDT implementations including:
4//! - Add-Wins Graph: Preserves deleted elements for potential recovery
5//! - Remove-Wins Graph: Completely removes deleted elements for memory efficiency
6//! - Graph algorithms: Path finding, connectivity analysis, etc.
7
8pub mod add_wins;
9pub mod algorithms;
10pub mod edge;
11pub mod remove_wins;
12pub mod vertex;
13
14// Re-export main types for convenience
15pub use add_wins::{AddWinsGraph, GraphConfig};
16pub use algorithms::GraphAlgorithms;
17pub use edge::{Edge, EdgeId, EdgeMetadata};
18pub use remove_wins::RemoveWinsGraph;
19pub use vertex::{GraphError, Vertex, VertexId, VertexMetadata};
20
21/// Strategy for handling graph conflicts
22#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
23pub enum GraphStrategy {
24    /// Add-Wins: Vertices and edges are never removed, only marked as deleted
25    AddWins,
26    /// Remove-Wins: Deleted vertices and edges are completely removed
27    RemoveWins,
28}
29
30#[cfg(test)]
31mod integration_tests {
32    use super::super::{ReplicaId, basic::traits::Mergeable};
33    use super::*;
34    use uuid::Uuid;
35
36    fn create_replica(id: u64) -> ReplicaId {
37        ReplicaId::from(Uuid::from_u64_pair(0, id))
38    }
39
40    #[test]
41    fn test_graph_module_integration() {
42        let replica = create_replica(1);
43
44        // Test Add-Wins Graph
45        let mut add_wins_graph = AddWinsGraph::new(replica);
46        let v1_id = add_wins_graph.add_vertex("vertex1", 1000);
47        let v2_id = add_wins_graph.add_vertex("vertex2", 2000);
48        let _edge_id = add_wins_graph.add_edge(&v1_id, &v2_id, 3000, None).unwrap();
49
50        assert_eq!(add_wins_graph.vertex_count(), 2);
51        assert_eq!(add_wins_graph.edge_count(), 1);
52
53        // Test Remove-Wins Graph
54        let mut remove_wins_graph = RemoveWinsGraph::new(replica);
55        let v1_id = remove_wins_graph.add_vertex("vertex1", 1000);
56        let v2_id = remove_wins_graph.add_vertex("vertex2", 2000);
57        let edge_id = remove_wins_graph
58            .add_edge(&v1_id, &v2_id, 3000, None)
59            .unwrap();
60
61        assert_eq!(remove_wins_graph.vertex_count(), 2);
62        assert_eq!(remove_wins_graph.edge_count(), 1);
63
64        // Test complete removal
65        remove_wins_graph.remove_edge(&edge_id).unwrap();
66        assert_eq!(remove_wins_graph.edge_count(), 0);
67    }
68
69    #[test]
70    fn test_graph_algorithms_integration() {
71        let replica = create_replica(1);
72        let mut graph = AddWinsGraph::new(replica);
73
74        // Create a simple path
75        let v1_id = graph.add_vertex("vertex1", 1000);
76        let v2_id = graph.add_vertex("vertex2", 2000);
77        let v3_id = graph.add_vertex("vertex3", 3000);
78
79        graph.add_edge(&v1_id, &v2_id, 4000, None).unwrap();
80        graph.add_edge(&v2_id, &v3_id, 5000, None).unwrap();
81
82        // Test shortest path algorithm
83        let path = graph.shortest_path(&v1_id, &v3_id).unwrap();
84        assert_eq!(path.len(), 3);
85        assert_eq!(path[0], v1_id);
86        assert_eq!(path[1], v2_id);
87        assert_eq!(path[2], v3_id);
88    }
89
90    #[test]
91    fn test_graph_merge_integration() {
92        let replica1 = create_replica(1);
93        let replica2 = create_replica(2);
94
95        let mut graph1 = AddWinsGraph::new(replica1);
96        let mut graph2 = AddWinsGraph::new(replica2);
97
98        // Add different vertices to each graph
99        let v1_id = graph1.add_vertex("vertex1", 1000);
100        let v2_id = graph2.add_vertex("vertex2", 2000);
101
102        // Merge graphs
103        graph1.merge(&graph2).unwrap();
104
105        // Both vertices should be present
106        assert_eq!(graph1.vertex_count(), 2);
107        assert!(graph1.contains_vertex(&v1_id));
108        assert!(graph1.contains_vertex(&v2_id));
109    }
110
111    #[test]
112    fn test_graph_configuration() {
113        let replica = create_replica(1);
114        let config = GraphConfig {
115            preserve_deleted: false,
116            max_vertices: Some(100),
117            max_edges: Some(200),
118            allow_self_loops: true,
119            allow_multiple_edges: true,
120        };
121
122        let graph: AddWinsGraph<String> = AddWinsGraph::with_config(replica, config);
123        assert_eq!(graph.config.max_vertices, Some(100));
124        assert_eq!(graph.config.allow_self_loops, true);
125        assert_eq!(graph.config.allow_multiple_edges, true);
126    }
127}