use nodedb_cluster::distributed_graph::stitch_components;
use nodedb_graph::{AlgoParams, GraphAlgorithm};
use crate::bridge::envelope::Payload;
use crate::control::server::graph_dispatch::bsp_pagerank::enumerate::enumerate_shards;
use crate::control::state::SharedState;
use crate::engine::graph::algo::result::AlgoResultBatch;
use crate::types::{DatabaseId, TenantId};
use super::scatter::scatter_wcc_round;
pub async fn run_bsp_wcc(
state: &SharedState,
tenant_id: TenantId,
database_id: DatabaseId,
params: AlgoParams,
deadline_ms: u64,
) -> crate::Result<Payload> {
let enumeration = enumerate_shards(state)?;
let targets = enumeration.targets;
if targets.is_empty() {
return empty_payload();
}
let results = scatter_wcc_round(
state,
tenant_id,
database_id,
¶ms,
&targets,
deadline_ms,
)
.await?;
let mut node_labels: Vec<(String, String)> = Vec::new();
let mut boundary_edges: Vec<(String, String)> = Vec::new();
for sr in results {
node_labels.extend(sr.result.node_labels);
boundary_edges.extend(sr.result.boundary_edges);
}
if node_labels.is_empty() {
return empty_payload();
}
let rows = stitch_components(node_labels, boundary_edges);
let mut batch = AlgoResultBatch::new(GraphAlgorithm::Wcc);
for (name, component_id) in rows {
batch.push_node_i64(name, component_id);
}
let bytes = batch.to_msgpack()?;
Ok(Payload::from_vec(bytes))
}
fn empty_payload() -> crate::Result<Payload> {
let bytes = AlgoResultBatch::new(GraphAlgorithm::Wcc).to_msgpack()?;
Ok(Payload::from_vec(bytes))
}