pub mod advanced;
pub mod analyticsconfig_traits;
pub mod analyticsoperation_traits;
pub mod centrality;
pub mod community;
pub mod executor;
pub mod paths;
pub mod patterns;
pub mod ranking;
pub mod stats_decomposition;
pub mod stats_distributions;
pub mod types;
pub use executor::execute_graph_analytics;
pub use types::*;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_analytics_operation_parsing() {
assert_eq!(
"pagerank".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::PageRank
);
assert_eq!(
"degree".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::DegreeDistribution
);
assert_eq!(
"community".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::CommunityDetection
);
assert_eq!(
"betweenness".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::BetweennessCentrality
);
assert_eq!(
"closeness".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::ClosenessCentrality
);
assert_eq!(
"eigenvector".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::EigenvectorCentrality
);
assert_eq!(
"bc".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::BetweennessCentrality
);
assert_eq!(
"cc".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::ClosenessCentrality
);
assert_eq!(
"ec".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::EigenvectorCentrality
);
assert_eq!(
"katz".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::KatzCentrality
);
assert_eq!(
"hits".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::HitsAlgorithm
);
assert_eq!(
"louvain".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::LouvainCommunities
);
assert_eq!(
"kc".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::KatzCentrality
);
assert_eq!(
"ha".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::HitsAlgorithm
);
assert_eq!(
"lc".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::LouvainCommunities
);
assert_eq!(
"kcore".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::KCoreDecomposition
);
assert_eq!(
"k-core".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::KCoreDecomposition
);
assert_eq!(
"triangles".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::TriangleCounting
);
assert_eq!(
"tc".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::TriangleCounting
);
assert_eq!(
"diameter".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::DiameterRadius
);
assert_eq!(
"radius".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::DiameterRadius
);
assert_eq!(
"dr".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::DiameterRadius
);
assert_eq!(
"center".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::CenterNodes
);
assert_eq!(
"cn".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::CenterNodes
);
assert_eq!(
"motifs".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::ExtendedMotifs
);
assert_eq!(
"em".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::ExtendedMotifs
);
assert_eq!(
"coloring".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::GraphColoring
);
assert_eq!(
"color".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::GraphColoring
);
assert_eq!(
"matching".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::MaximumMatching
);
assert_eq!(
"max-matching".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::MaximumMatching
);
assert_eq!(
"flow".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::NetworkFlow
);
assert_eq!(
"max-flow".parse::<AnalyticsOperation>().unwrap(),
AnalyticsOperation::NetworkFlow
);
}
#[test]
fn test_config_defaults() {
let config = AnalyticsConfig::default();
assert_eq!(config.damping_factor, 0.85);
assert_eq!(config.max_iterations, 100);
assert_eq!(config.tolerance, 1e-6);
assert_eq!(config.top_k, 20);
assert_eq!(config.katz_alpha, 0.1);
assert_eq!(config.katz_beta, 1.0);
assert_eq!(config.k_core_value, None);
assert!(config.enable_simd);
assert!(config.enable_parallel);
assert!(!config.enable_gpu);
}
#[test]
fn test_rdf_graph_construction() {
let mut graph = RdfGraph::new();
let id1 = graph.get_or_create_id("http://example.org/resource1".to_string());
let id2 = graph.get_or_create_id("http://example.org/resource2".to_string());
let id1_again = graph.get_or_create_id("http://example.org/resource1".to_string());
assert_eq!(id1, id1_again);
assert_ne!(id1, id2);
assert_eq!(graph.node_count(), 2);
graph.add_edge(id1, id2);
assert_eq!(graph.edge_count, 1);
assert_eq!(graph.out_degree(id1), 1);
assert_eq!(graph.out_degree(id2), 0);
}
#[test]
fn test_adjacency_matrix() {
let mut graph = RdfGraph::new();
let id0 = graph.get_or_create_id("http://example.org/node0".to_string());
let id1 = graph.get_or_create_id("http://example.org/node1".to_string());
let id2 = graph.get_or_create_id("http://example.org/node2".to_string());
graph.add_edge(id0, id1);
graph.add_edge(id0, id2);
graph.add_edge(id1, id2);
assert_eq!(graph.neighbors(id0).len(), 2);
assert_eq!(graph.neighbors(id1).len(), 1);
assert_eq!(graph.neighbors(id2).len(), 0);
let neighbors_0 = graph.neighbors(id0);
assert!(neighbors_0.contains(&id1));
assert!(neighbors_0.contains(&id2));
let neighbors_1 = graph.neighbors(id1);
assert_eq!(neighbors_1, &[id2]);
}
#[test]
fn test_scirs2_graph_conversion() {
let mut rdf_graph = RdfGraph::new();
let id0 = rdf_graph.get_or_create_id("http://example.org/a".to_string());
let id1 = rdf_graph.get_or_create_id("http://example.org/b".to_string());
let id2 = rdf_graph.get_or_create_id("http://example.org/c".to_string());
rdf_graph.add_edge(id0, id1);
rdf_graph.add_edge(id1, id2);
let scirs2_graph = rdf_graph.to_scirs2_graph().unwrap();
assert_eq!(scirs2_graph.node_count(), 3);
assert_eq!(scirs2_graph.edge_count(), 2);
assert!(scirs2_graph.has_node(&id0));
assert!(scirs2_graph.has_node(&id1));
assert!(scirs2_graph.has_node(&id2));
}
#[test]
fn test_graph_coloring_basic() {
let mut rdf_graph = RdfGraph::new();
let id0 = rdf_graph.get_or_create_id("http://example.org/a".to_string());
let id1 = rdf_graph.get_or_create_id("http://example.org/b".to_string());
let id2 = rdf_graph.get_or_create_id("http://example.org/c".to_string());
rdf_graph.add_edge(id0, id1);
rdf_graph.add_edge(id1, id2);
rdf_graph.add_edge(id2, id0);
let config = AnalyticsConfig {
operation: AnalyticsOperation::GraphColoring,
..Default::default()
};
let result = advanced::execute_graph_coloring(&rdf_graph, &config);
assert!(result.is_ok());
}
#[test]
fn test_graph_coloring_empty_graph() {
let rdf_graph = RdfGraph::new();
let config = AnalyticsConfig {
operation: AnalyticsOperation::GraphColoring,
..Default::default()
};
let result = advanced::execute_graph_coloring(&rdf_graph, &config);
assert!(result.is_ok());
}
#[test]
fn test_maximum_matching_basic() {
let mut rdf_graph = RdfGraph::new();
let id0 = rdf_graph.get_or_create_id("http://example.org/a".to_string());
let id1 = rdf_graph.get_or_create_id("http://example.org/b".to_string());
let id2 = rdf_graph.get_or_create_id("http://example.org/c".to_string());
let id3 = rdf_graph.get_or_create_id("http://example.org/d".to_string());
rdf_graph.add_edge(id0, id1);
rdf_graph.add_edge(id2, id3);
let config = AnalyticsConfig {
operation: AnalyticsOperation::MaximumMatching,
..Default::default()
};
let result = advanced::execute_maximum_matching(&rdf_graph, &config);
assert!(result.is_ok());
}
#[test]
fn test_maximum_matching_empty_graph() {
let rdf_graph = RdfGraph::new();
let config = AnalyticsConfig {
operation: AnalyticsOperation::MaximumMatching,
..Default::default()
};
let result = advanced::execute_maximum_matching(&rdf_graph, &config);
assert!(result.is_ok());
}
#[test]
fn test_network_flow_basic() {
let mut rdf_graph = RdfGraph::new();
let id0 = rdf_graph.get_or_create_id("http://example.org/source".to_string());
let id1 = rdf_graph.get_or_create_id("http://example.org/middle".to_string());
let id2 = rdf_graph.get_or_create_id("http://example.org/sink".to_string());
rdf_graph.add_edge(id0, id1);
rdf_graph.add_edge(id1, id2);
let config = AnalyticsConfig {
operation: AnalyticsOperation::NetworkFlow,
..Default::default()
};
let result = advanced::execute_network_flow(&rdf_graph, &config);
assert!(result.is_ok());
}
#[test]
fn test_network_flow_insufficient_nodes() {
let mut rdf_graph = RdfGraph::new();
rdf_graph.get_or_create_id("http://example.org/single".to_string());
let config = AnalyticsConfig {
operation: AnalyticsOperation::NetworkFlow,
..Default::default()
};
let result = advanced::execute_network_flow(&rdf_graph, &config);
assert!(result.is_ok());
}
#[test]
fn test_in_degree() {
let mut graph = RdfGraph::new();
let id0 = graph.get_or_create_id("http://example.org/a".to_string());
let id1 = graph.get_or_create_id("http://example.org/b".to_string());
let id2 = graph.get_or_create_id("http://example.org/c".to_string());
graph.add_edge(id0, id1);
graph.add_edge(id1, id2);
graph.add_edge(id0, id2);
assert_eq!(graph.in_degree(id0), 0);
assert_eq!(graph.in_degree(id1), 1);
assert_eq!(graph.in_degree(id2), 2);
}
#[test]
fn test_graph_stats_cache_creation() {
let cache = GraphStatsCache::new();
assert!(!cache.is_valid());
assert_eq!(cache.node_count, None);
assert_eq!(cache.edge_count, None);
assert_eq!(cache.density, None);
}
#[test]
fn test_graph_stats_cache_validity() {
let mut cache = GraphStatsCache::new();
assert!(!cache.is_valid());
cache.node_count = Some(100);
cache.computed_at = Some(std::time::Instant::now());
assert!(cache.is_valid());
assert!(cache.age().is_some());
}
#[test]
fn test_graph_metrics_creation() {
let metrics = GraphMetrics::new("PageRank", 100, 200, 0.02, 123.45);
assert_eq!(metrics.operation, "PageRank");
assert_eq!(metrics.node_count, 100);
assert_eq!(metrics.edge_count, 200);
assert!((metrics.density - 0.02).abs() < 1e-6);
assert!((metrics.computation_time_ms - 123.45).abs() < 1e-6);
}
#[test]
fn test_graph_metrics_with_results() {
let metrics = GraphMetrics::new("Test", 10, 20, 0.1, 50.0)
.with_results(serde_json::json!({ "key": "value" }));
assert_eq!(metrics.results, serde_json::json!({ "key": "value" }));
}
#[test]
fn test_benchmark_result_creation() {
let benchmark = BenchmarkResult::new("PageRank", 1000, 2000, 500.0, 100.0, 50.0, 350.0);
assert_eq!(benchmark.operation, "PageRank");
assert_eq!(benchmark.node_count, 1000);
assert_eq!(benchmark.edge_count, 2000);
assert!((benchmark.total_time_ms - 500.0).abs() < 1e-6);
assert!(benchmark.memory_used_mb > 0.0);
}
#[test]
fn test_analytics_config_defaults() {
let config = AnalyticsConfig::default();
assert!(config.enable_cache);
assert_eq!(config.export_path, None);
assert!(!config.enable_benchmarking);
assert!(config.enable_simd);
assert!(config.enable_parallel);
assert!(!config.enable_gpu);
}
#[test]
fn test_analytics_config_with_export() {
let config = AnalyticsConfig {
operation: AnalyticsOperation::PageRank,
export_path: Some("/tmp/metrics.json".to_string()),
enable_benchmarking: true,
..Default::default()
};
assert_eq!(config.export_path, Some("/tmp/metrics.json".to_string()));
assert!(config.enable_benchmarking);
}
}