blob: abca2122d212ac452345dd9fc654d92065b7fcab [file] [log] [blame]
use petgraph_core::{edge::EdgeId, node::NodeId};
use crate::{
closure::UniqueVec,
iter::closure::{
EdgeBetweenIterator, EdgeIdClosureIter, EdgeIntersectionIterator, EdgeIterator,
NeighbourIterator, NodeIdClosureIter,
},
slab::{EntryId, Key},
};
impl Key for NodeId {
#[inline]
fn from_id(id: EntryId) -> Self {
Self::new(id.into_usize())
}
#[inline]
fn into_id(self) -> EntryId {
EntryId::new_unchecked(self.into_inner())
}
}
pub(crate) type NodeSlab<T> = crate::slab::Slab<NodeId, Node<T>>;
#[derive(Debug, Clone)]
pub(crate) struct NodeClosures {
outgoing_nodes: UniqueVec<NodeId>,
incoming_nodes: UniqueVec<NodeId>,
outgoing_edges: UniqueVec<EdgeId>,
incoming_edges: UniqueVec<EdgeId>,
}
impl NodeClosures {
const fn new() -> Self {
Self {
outgoing_nodes: UniqueVec::new(),
incoming_nodes: UniqueVec::new(),
outgoing_edges: UniqueVec::new(),
incoming_edges: UniqueVec::new(),
}
}
pub(crate) fn insert_outgoing_node(&mut self, node: NodeId) {
self.outgoing_nodes.insert(node);
}
pub(crate) fn remove_outgoing_node(&mut self, node: NodeId) {
self.outgoing_nodes.remove(&node);
}
pub(crate) fn insert_incoming_node(&mut self, node: NodeId) {
self.incoming_nodes.insert(node);
}
pub(crate) fn remove_incoming_node(&mut self, node: NodeId) {
self.incoming_nodes.remove(&node);
}
pub(crate) fn insert_outgoing_edge(&mut self, edge: EdgeId) {
self.outgoing_edges.insert(edge);
}
pub(crate) fn remove_outgoing_edge(&mut self, edge: EdgeId) {
self.outgoing_edges.remove(&edge);
}
pub(crate) fn insert_incoming_edge(&mut self, edge: EdgeId) {
self.incoming_edges.insert(edge);
}
pub(crate) fn remove_incoming_edge(&mut self, edge: EdgeId) {
self.incoming_edges.remove(&edge);
}
pub(crate) fn outgoing_nodes(&self) -> NodeIdClosureIter {
self.outgoing_nodes.iter().copied()
}
pub(crate) fn incoming_nodes(&self) -> NodeIdClosureIter {
self.incoming_nodes.iter().copied()
}
pub(crate) fn neighbours(&self) -> NeighbourIterator {
NeighbourIterator::new(
self.outgoing_nodes.iter().copied(),
self.incoming_nodes.iter().copied(),
)
}
pub(crate) fn outgoing_edges(&self) -> EdgeIdClosureIter {
self.outgoing_edges.iter().copied()
}
pub(crate) fn incoming_edges(&self) -> EdgeIdClosureIter {
self.incoming_edges.iter().copied()
}
pub(crate) fn edges(&self) -> EdgeIterator {
EdgeIterator::new(
self.outgoing_edges.iter().copied(),
self.incoming_edges.iter().copied(),
)
}
pub(crate) fn edges_between_undirected<'a>(
&'a self,
other: &'a Self,
) -> EdgeBetweenIterator<'a> {
EdgeBetweenIterator::new(self, other)
}
pub(crate) fn edges_between_directed<'a>(
&'a self,
other: &'a Self,
) -> EdgeIntersectionIterator<'a> {
EdgeIntersectionIterator::new(
self.outgoing_edges.iter().copied(),
other.incoming_edges.iter().copied(),
)
}
pub(crate) fn is_isolated(&self) -> bool {
self.outgoing_nodes.is_empty() && self.incoming_nodes.is_empty()
}
pub(crate) fn clear(&mut self) {
self.outgoing_nodes.clear();
self.incoming_nodes.clear();
self.outgoing_edges.clear();
self.incoming_edges.clear();
}
}
#[derive(Debug, Clone)]
pub(crate) struct Node<T> {
pub(crate) id: NodeId,
pub(crate) weight: T,
pub(crate) closures: NodeClosures,
}
impl<T> Node<T> {
pub(crate) const fn new(id: NodeId, weight: T) -> Self {
Self {
id,
weight,
closures: NodeClosures::new(),
}
}
}
impl<T> PartialEq for Node<T>
where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
(self.id, &self.weight) == (other.id, &other.weight)
}
}
impl<T> Eq for Node<T> where T: Eq {}
impl<T> PartialOrd for Node<T>
where
T: PartialOrd,
{
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
(self.id, &self.weight).partial_cmp(&(other.id, &other.weight))
}
}
impl<T> Ord for Node<T>
where
T: Ord,
{
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
(self.id, &self.weight).cmp(&(other.id, &other.weight))
}
}