use std::collections::VecDeque;
use std::path::PathBuf;
use anyhow::{Context, Result};
use clap::Parser;
use dsi_progress_logger::{progress_logger, ProgressLog};
use log::{debug, info};
use sux::bits::bit_vec::BitVec;
use sux::traits::BitVecOpsMut;
use swh_graph::graph::*;
use swh_graph::mph::DynMphf;
#[derive(Parser, Debug)]
#[command(about, long_about = None)]
struct Args {
#[arg(short, long)]
graph: PathBuf,
#[arg(short, long)]
swhid: String,
}
pub fn main() -> Result<()> {
let args = Args::parse();
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
info!("Loading graph...");
let graph = SwhUnidirectionalGraph::new(args.graph)
.context("Could not load graph")?
.init_properties()
.load_properties(|properties| properties.load_maps::<DynMphf>())
.context("Could not load graph properties")?;
info!("looking up SWHID {} ...", args.swhid);
let node_id = graph
.properties()
.node_id(&*args.swhid)
.context("Unknown SWHID")?;
info!("obtained node ID {node_id} ...");
let num_nodes = graph.num_nodes();
let mut visited = BitVec::new(num_nodes);
let mut queue: VecDeque<usize> = VecDeque::new();
assert!(node_id < num_nodes);
queue.push_back(node_id);
let mut visited_nodes = 0;
let mut pl = progress_logger!(
display_memory = true,
item_name = "node",
local_speed = true,
expected_updates = Some(num_nodes),
);
pl.start("visiting graph ...");
while let Some(current_node) = queue.pop_front() {
let visited_swhid = graph.properties().swhid(current_node);
debug!("{visited_swhid}");
visited_nodes += 1;
for succ in graph.successors(current_node) {
if !visited[succ] {
queue.push_back(succ);
visited.set(succ as _, true);
pl.light_update();
}
}
}
pl.done();
info!("visit completed after visiting {visited_nodes} nodes.");
Ok(())
}