use webgraph::prelude::*;
use crate::graph::*;
pub struct WebgraphAdapter<G: SwhForwardGraph>(pub G);
impl<G: SwhForwardGraph> SequentialLabeling for WebgraphAdapter<G> {
type Label = usize;
type Lender<'node>
= LenderSwhForwardGraph<'node, G>
where
Self: 'node;
#[inline(always)]
fn num_nodes(&self) -> usize {
SwhGraph::num_nodes(&self.0)
}
#[inline(always)]
fn num_arcs_hint(&self) -> Option<u64> {
Some(SwhGraph::num_arcs(&self.0))
}
#[inline(always)]
fn iter_from(&self, node_id: usize) -> Self::Lender<'_> {
LenderSwhForwardGraph {
graph: &self.0,
node_id,
}
}
}
impl<G: SwhForwardGraph> RandomAccessLabeling for WebgraphAdapter<G> {
type Labels<'succ>
= <G as SwhForwardGraph>::Successors<'succ>
where
Self: 'succ;
#[inline(always)]
fn num_arcs(&self) -> u64 {
SwhGraph::num_arcs(&self.0)
}
#[inline(always)]
fn outdegree(&self, node_id: usize) -> usize {
SwhForwardGraph::outdegree(&self.0, node_id)
}
#[inline(always)]
fn labels(&self, node_id: NodeId) -> Self::Labels<'_> {
SwhForwardGraph::successors(&self.0, node_id)
}
}
impl<G: SwhForwardGraph> SequentialGraph for WebgraphAdapter<G> {}
impl<G: SwhForwardGraph> RandomAccessGraph for WebgraphAdapter<G> {}
pub struct LenderSwhForwardGraph<'node, G: SwhForwardGraph> {
graph: &'node G,
node_id: NodeId,
}
impl<'succ, G: SwhForwardGraph> lender::Lending<'succ> for LenderSwhForwardGraph<'_, G> {
type Lend = (usize, G::Successors<'succ>);
}
impl<'succ, G: SwhForwardGraph> NodeLabelsLender<'succ> for LenderSwhForwardGraph<'_, G> {
type Label = usize;
type IntoIterator = G::Successors<'succ>;
}
unsafe impl<G: SwhForwardGraph> SortedLender for LenderSwhForwardGraph<'_, G> where
for<'succ> <G as SwhForwardGraph>::Successors<'succ>: SortedLender
{
}
impl<G: SwhForwardGraph> lender::Lender for LenderSwhForwardGraph<'_, G> {
lender::unsafe_assume_covariance!();
fn next(&mut self) -> Option<<Self as lender::Lending<'_>>::Lend> {
let node_id = self.node_id;
if node_id >= self.graph.num_nodes() {
return None;
}
self.node_id += 1;
Some((node_id, self.graph.successors(node_id)))
}
}
pub struct SymmetricWebgraphAdapter<G: SwhForwardGraph + SwhBackwardGraph>(pub G);
impl<G: SwhForwardGraph + SwhBackwardGraph> SequentialLabeling for SymmetricWebgraphAdapter<G>
where
for<'succ> <<G as SwhForwardGraph>::Successors<'succ> as IntoIterator>::IntoIter:
SortedIterator,
for<'pred> <<G as SwhBackwardGraph>::Predecessors<'pred> as IntoIterator>::IntoIter:
SortedIterator,
{
type Label = usize;
type Lender<'node>
= LenderSwhSymmetricGraph<'node, G>
where
Self: 'node;
#[inline(always)]
fn num_nodes(&self) -> usize {
SwhGraph::num_nodes(&self.0)
}
#[inline(always)]
fn num_arcs_hint(&self) -> Option<u64> {
Some(SwhGraph::num_arcs(&self.0) * 2)
}
#[inline(always)]
fn iter_from(&self, node_id: usize) -> Self::Lender<'_> {
LenderSwhSymmetricGraph {
graph: &self.0,
node_id,
}
}
}
impl<G: SwhForwardGraph + SwhBackwardGraph> RandomAccessLabeling for SymmetricWebgraphAdapter<G>
where
for<'succ> <<G as SwhForwardGraph>::Successors<'succ> as IntoIterator>::IntoIter:
SortedIterator,
for<'pred> <<G as SwhBackwardGraph>::Predecessors<'pred> as IntoIterator>::IntoIter:
SortedIterator,
{
type Labels<'succ>
= MergedSuccessorsForGraph<'succ, G>
where
Self: 'succ;
#[inline(always)]
fn num_arcs(&self) -> u64 {
SwhGraph::num_arcs(&self.0) * 2
}
#[inline(always)]
fn outdegree(&self, node_id: usize) -> usize {
SwhForwardGraph::outdegree(&self.0, node_id) + SwhBackwardGraph::indegree(&self.0, node_id)
}
#[inline(always)]
fn labels(&self, node_id: NodeId) -> Self::Labels<'_> {
webgraph::graphs::union_graph::Succ::new(
Some(<G as SwhForwardGraph>::successors(&self.0, node_id).into_iter()),
Some(<G as SwhBackwardGraph>::predecessors(&self.0, node_id).into_iter()),
)
}
}
impl<G: SwhForwardGraph + SwhBackwardGraph> SequentialGraph for SymmetricWebgraphAdapter<G>
where
for<'succ> <<G as SwhForwardGraph>::Successors<'succ> as IntoIterator>::IntoIter:
SortedIterator,
for<'pred> <<G as SwhBackwardGraph>::Predecessors<'pred> as IntoIterator>::IntoIter:
SortedIterator,
{
}
impl<G: SwhForwardGraph + SwhBackwardGraph> RandomAccessGraph for SymmetricWebgraphAdapter<G>
where
for<'succ> <<G as SwhForwardGraph>::Successors<'succ> as IntoIterator>::IntoIter:
SortedIterator,
for<'pred> <<G as SwhBackwardGraph>::Predecessors<'pred> as IntoIterator>::IntoIter:
SortedIterator,
{
}
type MergedSuccessors<S1, S2> = webgraph::graphs::union_graph::Succ<S1, S2>;
type MergedSuccessorsForGraph<'succ, G> = MergedSuccessors<
<<G as SwhForwardGraph>::Successors<'succ> as IntoIterator>::IntoIter,
<<G as SwhBackwardGraph>::Predecessors<'succ> as IntoIterator>::IntoIter,
>;
pub struct LenderSwhSymmetricGraph<'node, G: SwhForwardGraph + SwhBackwardGraph> {
graph: &'node G,
node_id: NodeId,
}
impl<'succ, G: SwhForwardGraph + SwhBackwardGraph> lender::Lending<'succ>
for LenderSwhSymmetricGraph<'_, G>
{
type Lend = (usize, MergedSuccessorsForGraph<'succ, G>);
}
impl<'succ, G: SwhForwardGraph + SwhBackwardGraph> NodeLabelsLender<'succ>
for LenderSwhSymmetricGraph<'_, G>
{
type Label = usize;
type IntoIterator = MergedSuccessorsForGraph<'succ, G>;
}
unsafe impl<G: SwhForwardGraph + SwhBackwardGraph> SortedLender for LenderSwhSymmetricGraph<'_, G>
where
for<'succ> <G as SwhForwardGraph>::Successors<'succ>: SortedLender,
for<'succ> <G as SwhBackwardGraph>::Predecessors<'succ>: SortedLender,
{
}
impl<G: SwhForwardGraph + SwhBackwardGraph> lender::Lender for LenderSwhSymmetricGraph<'_, G> {
lender::unsafe_assume_covariance!();
fn next(&mut self) -> Option<<Self as lender::Lending<'_>>::Lend> {
let node_id = self.node_id;
if node_id >= self.graph.num_nodes() {
return None;
}
self.node_id += 1;
Some((
node_id,
webgraph::graphs::union_graph::Succ::new(
Some(<G as SwhForwardGraph>::successors(self.graph, node_id).into_iter()),
Some(<G as SwhBackwardGraph>::predecessors(self.graph, node_id).into_iter()),
),
))
}
}