use std::path::PathBuf;
use anyhow::Result;
use clap::ValueEnum;
use dsi_progress_logger::{progress_logger, ProgressLog};
use sux::prelude::BitVec;
use swh_graph::graph::*;
use swh_graph::NodeType;
#[derive(ValueEnum, Debug, Clone, Copy)]
pub enum NodeFilter {
Heads,
All,
}
pub fn load_reachable_nodes<G>(
graph: &G,
node_filter: NodeFilter,
path: PathBuf,
) -> Result<Option<BitVec>>
where
G: SwhGraph + Sync,
{
match node_filter {
NodeFilter::All => Ok(None),
_ => {
let mut pl = progress_logger!(
item_name = "node",
display_memory = true,
local_speed = true,
);
pl.start("Loading reachable nodes...");
let reachable_nodes = crate::frontier_set::from_parquet(&graph, path, &mut pl)?;
pl.done();
Ok(Some(reachable_nodes))
}
}
}
pub fn is_head<G>(graph: &G, node_id: NodeId) -> bool
where
G: SwhBackwardGraph + SwhGraphWithProperties,
<G as SwhGraphWithProperties>::Maps: swh_graph::properties::Maps,
{
let node_type = graph.properties().node_type(node_id);
match node_type {
NodeType::Release => true,
NodeType::Revision => graph.predecessors(node_id).into_iter().any(|pred| {
let pred_type = graph.properties().node_type(pred);
pred_type == NodeType::Snapshot || pred_type == NodeType::Release
}),
NodeType::Origin | NodeType::Snapshot | NodeType::Directory | NodeType::Content => false,
}
}
pub fn is_root_revrel<G>(graph: &G, node_filter: NodeFilter, node_id: NodeId) -> bool
where
G: SwhBackwardGraph + SwhGraphWithProperties,
<G as SwhGraphWithProperties>::Maps: swh_graph::properties::Maps,
{
match node_filter {
NodeFilter::All => {
let node_type = graph.properties().node_type(node_id);
node_type == NodeType::Release || node_type == NodeType::Revision
}
NodeFilter::Heads => is_head(graph, node_id),
}
}