use crate::core::*;
use std::{
collections::HashMap,
fmt::{Debug, Display},
hash::Hash,
sync::{Arc, Weak}
};
pub trait Graph<K, N, E>
where
K: Hash + Eq + Clone + Debug + Display + Sync + Send,
N: Clone + Debug + Display + Sync + Send,
E: Clone + Debug + Display + Sync + Send,
{
fn new() -> Self;
fn directed() -> bool;
fn add_node(&mut self, key: K, data: N) -> bool;
fn get_node(&self, node: K) -> Option<Arc<Node<K, N, E>>>;
fn iter_nodes(&self, f: &dyn Fn (Arc<Node<K, N, E>>));
fn node_count(&self) -> usize;
fn add_edge(&mut self, source: K, target: K, data: E) -> bool {
let s = self.get_node(source);
let t = self.get_node(target);
match s {
Some(src) => {
match t {
Some(trg) => {
connect(&src, &trg, data);
true
}
None => { false }
}
}
None => { false }
}
}
fn del_edge(&mut self, source: K, target: K) -> bool {
let s = self.get_node(source);
let t = self.get_node(target);
match s {
Some(src) => {
match t {
Some(trg) => {
disconnect(&src, &trg);
true
}
None => { false }
}
}
None => { false }
}
}
fn get_edge(&self, source: K, target: K) -> Option<Arc<Edge<K, N, E>>> {
let s = self.get_node(source);
let t = self.get_node(target);
match s {
Some(ss) => match t {
Some(tt) => ss.find_outbound(&tt),
None => None,
},
None => None,
}
}
fn edge_count(&self) -> usize {
let r : std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0);
self.iter_nodes(&|n| {
let o = r.load(std::sync::atomic::Ordering::Relaxed);
r.store(o + n.outbound().len(), std::sync::atomic::Ordering::Relaxed);
});
r.load(std::sync::atomic::Ordering::Relaxed)
}
fn size_of(&self) -> usize {
(self.node_count() * std::mem::size_of::<Node<K, N, E>>())
+ (self.edge_count() * std::mem::size_of::<Edge<K, N, E>>())
}
fn depth_first<F>(&self, source: K, explorer: F) -> Option<Vec<Weak<Edge<K, N, E>>>>
where
F: Fn (&Arc<Edge<K, N, E>>) -> Traverse,
{
match self.get_node(source) {
Some(s) => {
match Self::directed() {
true => { directed_depth_traversal(&s, explorer) }
false => { undirected_depth_traversal(&s, explorer) }
}
}
None => None
}
}
fn breadth_first<F>(&self, source: K, explorer: F) -> Option<Vec<Weak<Edge<K, N, E>>>>
where
F: Fn (&Arc<Edge<K, N, E>>) -> Traverse + Sync + Send + Copy,
{
match self.get_node(source) {
Some(s) => {
match Self::directed() {
true => { directed_breadth_traversal(&s, explorer) }
false => { undirected_breadth_traversal(&s, explorer) }
}
}
None => None
}
}
fn par_breadth_first<F>(&self, source: K, explorer: F) -> Option<Vec<Weak<Edge<K, N, E>>>>
where
F: Fn (&Arc<Edge<K, N, E>>) -> Traverse + Sync + Send + Copy,
{
match self.get_node(source) {
Some(s) => {
match Self::directed() {
true => { parallel_directed_breadth_traversal(&s, explorer) }
false => { parallel_undirected_breadth_traversal(&s, explorer) }
}
}
None => None
}
}
fn print_nodes(&self) {
self.iter_nodes(&| node | {
println!(" {}", node);
})
}
fn print_edges(&self) {
let sign;
match Self::directed() {
true => { sign = "->"}
false => { sign = "--" }
}
self.iter_nodes(&| node | {
for edge in node.outbound().iter() {
println!(" {} {} {} [label = \"{}\"]",
edge.source().key(),
sign,
edge.target().key(),
edge.load())
}
})
}
fn print_graph(&self) {
let name;
match Self::directed() {
true => { name = "digraph"}
false => { name = "graph" }
}
println!("{} {{", name);
self.print_nodes();
self.print_edges();
println!("}}");
}
}
pub struct Ungraph<K, N = Empty, E = Empty>
where
K: Hash + Eq + Clone + Debug + Display + Sync + Send,
N: Clone + Debug + Display + Sync + Send,
E: Clone + Debug + Display + Sync + Send,
{
nodes: HashMap<K, Arc<Node<K, N, E>>>,
}
impl<K, N, E> Graph<K, N, E> for Ungraph<K, N, E>
where
K: Hash + Eq + Clone + Debug + Display + Sync + Send,
N: Clone + Debug + Display + Sync + Send,
E: Clone + Debug + Display + Sync + Send,
{
fn new() -> Self {
Self {
nodes: HashMap::new(),
}
}
fn directed() -> bool {
false
}
fn add_node(&mut self, key: K, data: N) -> bool {
if self.nodes.contains_key(&key) {
false
} else {
let node = Arc::new(Node::new(key.clone(), data));
self.nodes.insert(key, node);
true
}
}
fn get_node(&self, node: K) -> Option<Arc<Node<K, N, E>>> {
match self.nodes.get(&node) {
Some(n) => { Some(n.clone()) }
None => None
}
}
fn iter_nodes(&self, f: &dyn Fn (Arc<Node<K, N, E>>)) {
for (_, node) in self.nodes.iter() {
f(node.clone());
}
}
fn node_count(&self) -> usize {
self.nodes.len()
}
}
pub struct Digraph<K, N = Empty, E = Empty>
where
K: Hash + Eq + Clone + Debug + Display + Sync + Send,
N: Clone + Debug + Display + Sync + Send,
E: Clone + Debug + Display + Sync + Send,
{
nodes: HashMap<K, Arc<Node<K, N, E>>>,
}
impl<K, N, E> Graph<K, N, E> for Digraph<K, N, E>
where
K: Hash + Eq + Clone + Debug + Display + Sync + Send,
N: Clone + Debug + Display + Sync + Send,
E: Clone + Debug + Display + Sync + Send,
{
fn new() -> Self {
Self {
nodes: HashMap::new(),
}
}
fn directed() -> bool {
true
}
fn add_node(&mut self, key: K, data: N) -> bool {
if self.nodes.contains_key(&key) {
false
} else {
let node = Arc::new(Node::new(key.clone(), data));
self.nodes.insert(key, node);
true
}
}
fn get_node(&self, node: K) -> Option<Arc<Node<K, N, E>>> {
match self.nodes.get(&node) {
Some(n) => { Some(n.clone()) }
None => None
}
}
fn iter_nodes(&self, f: &dyn Fn (Arc<Node<K, N, E>>)) {
for (_, node) in self.nodes.iter() {
f(node.clone());
}
}
fn node_count(&self) -> usize {
self.nodes.len()
}
}