Struct SeqIter

Source
pub struct SeqIter<'a, S, G: RandomAccessGraph, P, const PRED: bool> { /* private fields */ }
Expand description

Sequential depth-first visits.

This is an iterative implementation that does not need a large stack size.

There are three version of the visit, which are type aliases to the same common implementation: SeqNoPred, SeqPred and SeqPath (the generic implementation should not be instantiated by the user).

  • SeqNoPred does not keep track of predecessors, nor of nodes on the stack; it can be used, for example, to compute reachability information.
  • SeqPred keeps track of predecessors, but not of nodes on the stack; it can be used, for example, to compute a topological sort.
  • SeqPath keeps track of predecessors and nodes on the stack; it can be used, for example, to establish acyclicity).

Each type of visit uses incrementally more space:

  • SeqNoPred uses one bit per node to remember known nodes and a stack of iterators, one for each node on the visit path.
  • SeqPred uses one bit per node to remember known nodes and a stack of pairs made of an iterator and a predecessor, one for each node on the visit path.
  • SeqPath uses two bits per node to remember known nodes and whether the node is on the visit path, and a stack of pairs made of an iterator and a predecessor, one for each node on the visit path.

The visits differ also in the type of events they generate:

With respect to EventNoPred, EventPred provides the predecessor of the current node and a postvisit event.

If the visit was interrupted, the nodes still on the visit path can be retrieved using the stack method (only for SeqPred and SeqPath).

§Examples

Let’s test acyclicity:

use webgraph_algo::visits::*;
use webgraph_algo::visits::depth_first::*;
use webgraph::graphs::vec_graph::VecGraph;
use webgraph::traits::SequentialLabeling;
use webgraph::labels::proj::Left;
use std::ops::ControlFlow::*;

let graph = VecGraph::from_arcs([(0, 1), (1, 2), (2, 0), (1, 3)]);
let mut visit = depth_first::SeqPath::new(&graph);

assert!(visit.visit(
    0..graph.num_nodes(),
    |event| {
        match event {
            // Stop the visit as soon as a back edge is found
            EventPred::Revisit { on_stack: true, .. } => Break(StoppedWhenDone),
            _ => Continue(()),
        }
    },
).is_break()); // As the graph is not acyclic

Or, assuming the input is acyclic, let us compute the reverse of a topological sort:

use webgraph_algo::visits::*;
use webgraph_algo::visits::depth_first::*;
use webgraph::graphs::vec_graph::VecGraph;
use webgraph::labels::proj::Left;
use webgraph::traits::labels::SequentialLabeling;
use std::ops::ControlFlow::Continue;
use no_break::NoBreak;

let graph = VecGraph::from_arcs([(0, 1), (1, 2), (1, 3), (0, 3)]);
let mut visit = depth_first::SeqPred::new(&graph);
let mut top_sort = Vec::with_capacity(graph.num_nodes());

visit.visit(
    0..graph.num_nodes(),
    |event| {
        if let EventPred::Postvisit { node, .. } = event {
            top_sort.push(node);
        }
        Continue(())
    }
).continue_value_no_break();

Implementations§

Source§

impl<'a, S: NodeStates, G: RandomAccessGraph, P, const PRED: bool> SeqIter<'a, S, G, P, PRED>

Source

pub fn new(graph: &'a G) -> SeqIter<'a, S, G, P, PRED>

Creates a new sequential visit.

§Arguments
  • graph: an immutable reference to the graph to visit.
Source§

impl<'a, S, G: RandomAccessGraph> SeqIter<'a, S, G, usize, true>

Source

pub fn stack(&mut self) -> StackIterator<'a, '_, S, G>

Returns an iterator over the nodes still on the visit path, except for the last one.

Node will be returned in reverse order of visit.

This method is useful only in the case of interrupted visits, as in a completed visit the stack will be empty. The last node on the visit path at the moment of the interruption must be treated separately.

Trait Implementations§

Source§

impl<S: NodeStates, G: RandomAccessGraph> Sequential<EventPred> for SeqIter<'_, S, G, usize, true>

Source§

fn visit_filtered_with<R: IntoIterator<Item = usize>, T, E, C: FnMut(&mut T, EventPred) -> ControlFlow<E, ()>, F: FnMut(&mut T, FilterArgsPred) -> bool>( &mut self, roots: R, init: T, callback: C, filter: F, ) -> ControlFlow<E, ()>

Visits the graph from the specified nodes with an initialization value and a filter function. Read more
Source§

fn reset(&mut self)

Resets the visit status, making it possible to reuse it.
Source§

fn visit_filtered<R: IntoIterator<Item = usize>, E, C: FnMut(A) -> ControlFlow<E, ()>, F: FnMut(A::FilterArgs) -> bool>( &mut self, roots: R, callback: C, filter: F, ) -> ControlFlow<E, ()>

Visits the graph from the specified nodes with a filter function. Read more
Source§

fn visit_with<R: IntoIterator<Item = usize>, T, E, C: FnMut(&mut T, A) -> ControlFlow<E, ()>>( &mut self, roots: R, init: T, callback: C, ) -> ControlFlow<E, ()>

Visits the graph from the specified nodes with an initialization value. Read more
Source§

fn visit<R: IntoIterator<Item = usize>, E, C: FnMut(A) -> ControlFlow<E, ()>>( &mut self, roots: R, callback: C, ) -> ControlFlow<E, ()>

Visits the graph from the specified nodes. Read more

Auto Trait Implementations§

§

impl<'a, S, G, P, const PRED: bool> Freeze for SeqIter<'a, S, G, P, PRED>
where S: Freeze,

§

impl<'a, S, G, P, const PRED: bool> RefUnwindSafe for SeqIter<'a, S, G, P, PRED>

§

impl<'a, S, G, P, const PRED: bool> Send for SeqIter<'a, S, G, P, PRED>
where S: Send, G: Sync, <<G as RandomAccessLabeling>::Labels<'a> as IntoIterator>::IntoIter: Send, P: Send,

§

impl<'a, S, G, P, const PRED: bool> Sync for SeqIter<'a, S, G, P, PRED>
where S: Sync, G: Sync, <<G as RandomAccessLabeling>::Labels<'a> as IntoIterator>::IntoIter: Sync, P: Sync,

§

impl<'a, S, G, P, const PRED: bool> Unpin for SeqIter<'a, S, G, P, PRED>

§

impl<'a, S, G, P, const PRED: bool> UnwindSafe for SeqIter<'a, S, G, P, PRED>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CastableFrom<T> for T

Source§

fn cast_from(value: T) -> T

Call Self as W
Source§

impl<T> CastableFrom<T> for T

Source§

fn cast_from(value: T) -> T

Call Self as W
Source§

impl<T, U> CastableInto<U> for T
where U: CastableFrom<T>,

Source§

fn cast(self) -> U

Call W::cast_from(self)
Source§

impl<T, U> CastableInto<U> for T
where U: CastableFrom<T>,

Source§

fn cast(self) -> U

Call W::cast_from(self)
Source§

impl<T> DowncastableFrom<T> for T

Source§

fn downcast_from(value: T) -> T

Truncate the current UnsignedInt to a possibly smaller size
Source§

impl<T> DowncastableFrom<T> for T

Source§

fn downcast_from(value: T) -> T

Truncate the current UnsignedInt to a possibly smaller size
Source§

impl<T, U> DowncastableInto<U> for T
where U: DowncastableFrom<T>,

Source§

fn downcast(self) -> U

Call W::downcast_from(self)
Source§

impl<T, U> DowncastableInto<U> for T
where U: DowncastableFrom<T>,

Source§

fn downcast(self) -> U

Call W::downcast_from(self)
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Splat<T> for T

Source§

fn splat(value: T) -> T

Source§

impl<T> Splat<T> for T

Source§

fn splat(value: T) -> T

Source§

impl<T> To<T> for T

Source§

fn to(self) -> T

Source§

impl<T> To<T> for T

Source§

fn to(self) -> T

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> UpcastableFrom<T> for T

Source§

fn upcast_from(value: T) -> T

Extend the current UnsignedInt to a possibly bigger size.
Source§

impl<T> UpcastableFrom<T> for T

Source§

fn upcast_from(value: T) -> T

Extend the current UnsignedInt to a possibly bigger size.
Source§

impl<T, U> UpcastableInto<U> for T
where U: UpcastableFrom<T>,

Source§

fn upcast(self) -> U

Call W::upcast_from(self)
Source§

impl<T, U> UpcastableInto<U> for T
where U: UpcastableFrom<T>,

Source§

fn upcast(self) -> U

Call W::upcast_from(self)
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V