use crate::traits::IndexGraph;
use std::collections::HashMap;
use std::hash::{BuildHasher, Hash};
pub trait ItemMap<K, V>
where
K: Copy,
{
fn is_empty(&self) -> bool {
self.len() == 0
}
fn len(&self) -> usize;
fn clear(&mut self);
fn insert(&mut self, key: K, value: V) -> bool;
fn insert_or_replace(&mut self, key: K, value: V) -> bool;
fn remove(&mut self, key: K) -> bool;
fn get(&self, key: K) -> Option<&V>;
fn get_mut(&mut self, key: K) -> Option<&mut V>;
fn contains(&self, key: K) -> bool;
}
impl<'a, K, V, S> ItemMap<K, V> for &'a mut S
where
K: Copy,
S: ItemMap<K, V>,
{
fn is_empty(&self) -> bool {
(**self).is_empty()
}
fn len(&self) -> usize {
(**self).len()
}
fn clear(&mut self) {
(**self).clear()
}
fn insert(&mut self, key: K, value: V) -> bool {
(**self).insert(key, value)
}
fn insert_or_replace(&mut self, key: K, value: V) -> bool {
(**self).insert_or_replace(key, value)
}
fn remove(&mut self, key: K) -> bool {
(**self).remove(key)
}
fn get(&self, key: K) -> Option<&V> {
(**self).get(key)
}
fn get_mut(&mut self, key: K) -> Option<&mut V> {
(**self).get_mut(key)
}
fn contains(&self, key: K) -> bool {
(**self).contains(key)
}
}
impl<K, V, S> ItemMap<K, V> for HashMap<K, V, S>
where
K: Copy + Eq + Hash,
S: BuildHasher,
{
fn is_empty(&self) -> bool {
HashMap::is_empty(self)
}
fn len(&self) -> usize {
HashMap::len(self)
}
fn clear(&mut self) {
HashMap::clear(self)
}
fn insert(&mut self, key: K, value: V) -> bool {
let mut new = false;
HashMap::entry(self, key).or_insert_with(|| {
new = true;
value
});
new
}
fn insert_or_replace(&mut self, key: K, value: V) -> bool {
HashMap::insert(self, key, value).is_some()
}
fn remove(&mut self, key: K) -> bool {
HashMap::remove(self, &key).is_some()
}
fn get(&self, key: K) -> Option<&V> {
HashMap::get(self, &key)
}
fn get_mut(&mut self, key: K) -> Option<&mut V> {
HashMap::get_mut(self, &key)
}
fn contains(&self, key: K) -> bool {
HashMap::contains_key(self, &key)
}
}
pub struct NodeVecMap<'a, G, V> {
graph: &'a G,
data: Vec<Option<V>>,
nitems: usize,
}
impl<'a, G, V> NodeVecMap<'a, G, V>
where
G: IndexGraph,
V: Clone,
{
pub fn new(g: &'a G) -> Self {
NodeVecMap {
graph: g,
data: vec![None; g.num_nodes()],
nitems: 0,
}
}
}
impl<'a, G, V> ItemMap<G::Node<'a>, V> for NodeVecMap<'a, G, V>
where
G: IndexGraph,
V: Clone,
{
fn is_empty(&self) -> bool {
self.nitems == 0
}
fn len(&self) -> usize {
self.nitems
}
fn clear(&mut self) {
self.nitems = 0;
self.data.fill(None)
}
fn insert(&mut self, key: G::Node<'a>, value: V) -> bool {
let i = self.graph.node_id(key);
if self.data[i].is_none() {
self.data[i] = Some(value);
true
} else {
false
}
}
fn insert_or_replace(&mut self, key: G::Node<'a>, value: V) -> bool {
self.data[self.graph.node_id(key)].replace(value).is_none()
}
fn remove(&mut self, key: G::Node<'a>) -> bool {
self.data[self.graph.node_id(key)].take().is_some()
}
fn get(&self, key: G::Node<'a>) -> Option<&V> {
self.data[self.graph.node_id(key)].as_ref()
}
fn get_mut(&mut self, key: G::Node<'a>) -> Option<&mut V> {
self.data[self.graph.node_id(key)].as_mut()
}
fn contains(&self, key: G::Node<'a>) -> bool {
self.data[self.graph.node_id(key)].is_some()
}
}