use crate::index::GraphIndex;
use crate::interface::subgraph::DecoratingSubgraph;
use crate::interface::{GraphBase, ImmutableGraphContainer};
type IntegerType = usize;
pub struct IncrementalSubgraph<'a, Graph: GraphBase> {
parent_graph: &'a Graph,
present_nodes: Vec<IntegerType>,
present_edges: Vec<IntegerType>,
new_nodes: Vec<Vec<Graph::NodeIndex>>,
new_edges: Vec<Vec<Graph::EdgeIndex>>,
current_step: IntegerType,
}
impl<'a, Graph: ImmutableGraphContainer> IncrementalSubgraph<'a, Graph> {
pub fn new_with_incremental_steps(
graph: <Self as DecoratingSubgraph>::ParentGraphRef,
incremental_steps: usize,
) -> Self {
Self {
parent_graph: graph,
present_nodes: vec![IntegerType::max_value(); graph.node_count()],
present_edges: vec![IntegerType::max_value(); graph.edge_count()],
new_nodes: vec![Default::default(); incremental_steps],
new_edges: vec![Default::default(); incremental_steps],
current_step: 0,
}
}
pub fn set_current_step(&mut self, current_step: IntegerType) {
debug_assert!(current_step < self.new_nodes.len() && current_step < self.new_edges.len());
self.current_step = current_step;
}
pub fn new_nodes(&self) -> &Vec<Graph::NodeIndex> {
debug_assert!(self.current_step < self.new_nodes.len());
&self.new_nodes[self.current_step]
}
pub fn new_edges(&self) -> &Vec<Graph::EdgeIndex> {
debug_assert!(self.current_step < self.new_edges.len());
&self.new_edges[self.current_step]
}
}
impl<'a, Graph: ImmutableGraphContainer> DecoratingSubgraph for IncrementalSubgraph<'a, Graph> {
type ParentGraph = Graph;
type ParentGraphRef = &'a Graph;
fn new_empty(_graph: Self::ParentGraphRef) -> Self {
unimplemented!()
}
fn new_full(_graph: Self::ParentGraphRef) -> Self {
unimplemented!()
}
fn clear(&mut self) {
for node in &mut self.present_nodes {
*node = IntegerType::max_value();
}
for edge in &mut self.present_edges {
*edge = IntegerType::max_value();
}
for nodes in &mut self.new_nodes {
nodes.clear();
}
for edges in &mut self.new_edges {
edges.clear();
}
}
fn parent_graph(&self) -> &Self::ParentGraph {
self.parent_graph
}
fn contains_node(&self, node_index: <Self::ParentGraph as GraphBase>::NodeIndex) -> bool {
debug_assert!(node_index.as_usize() < self.present_nodes.capacity());
self.present_nodes[node_index.as_usize()] <= self.current_step
}
fn contains_edge(&self, edge_index: <Self::ParentGraph as GraphBase>::EdgeIndex) -> bool {
debug_assert!(edge_index.as_usize() < self.present_edges.capacity());
self.present_edges[edge_index.as_usize()] <= self.current_step
}
fn add_node(&mut self, node_index: <Self::ParentGraph as GraphBase>::NodeIndex) {
debug_assert!(node_index.as_usize() < self.present_nodes.capacity());
if self.present_nodes[node_index.as_usize()] > self.current_step {
debug_assert_eq!(
self.present_nodes[node_index.as_usize()],
IntegerType::max_value()
);
self.present_nodes[node_index.as_usize()] = self.current_step;
self.new_nodes[self.current_step].push(node_index);
}
}
fn add_edge(&mut self, edge_index: <Self::ParentGraph as GraphBase>::EdgeIndex) {
debug_assert!(edge_index.as_usize() < self.present_edges.capacity());
if self.present_edges[edge_index.as_usize()] > self.current_step {
debug_assert_eq!(
self.present_edges[edge_index.as_usize()],
IntegerType::max_value()
);
self.present_edges[edge_index.as_usize()] = self.current_step;
self.new_edges[self.current_step].push(edge_index);
}
}
fn remove_node(&mut self, node_index: <Self::ParentGraph as GraphBase>::NodeIndex) {
debug_assert!(node_index.as_usize() < self.present_nodes.capacity());
self.present_nodes[node_index.as_usize()] =
self.present_nodes[node_index.as_usize()].max(self.current_step + 1);
unimplemented!("This method is not intended to be called on an incremental subgraph.");
}
fn remove_edge(&mut self, edge_index: <Self::ParentGraph as GraphBase>::EdgeIndex) {
debug_assert!(edge_index.as_usize() < self.present_edges.capacity());
self.present_edges[edge_index.as_usize()] =
self.present_edges[edge_index.as_usize()].max(self.current_step + 1);
unimplemented!("This method is not intended to be called on an incremental subgraph.");
}
fn node_count(&self) -> usize {
self.present_nodes
.iter()
.filter(|&&n| n <= self.current_step)
.count()
}
fn edge_count(&self) -> usize {
self.present_edges
.iter()
.filter(|&&n| n <= self.current_step)
.count()
}
}