use std::{collections::BTreeMap, iter::FusedIterator};
#[derive(Debug, Clone)]
pub struct IndexedGraph<K, V> {
keys: Vec<K>,
values: Vec<V>,
edges: BTreeMap<K, K>,
i: BTreeMap<K, Vec<usize>>,
}
impl<K: Ord + Clone, V> IndexedGraph<K, V> {
pub fn new() -> IndexedGraph<K, V> {
IndexedGraph {
keys: vec![],
values: vec![],
edges: BTreeMap::new(),
i: BTreeMap::new(),
}
}
pub fn clear(&mut self) {
*self = IndexedGraph::new();
}
pub fn get(&self, key: &K) -> Vec<&V> {
let mut res = vec![];
if let Some(indexes) = self.i.get(key) {
for idx in indexes {
res.push(&self.values[*idx]);
}
}
return res;
}
pub fn get_key_values(&self, key: &K) -> Vec<(&K, &V)> {
let mut res = vec![];
if let Some(tup) = self.i.get_key_value(key) {
for idx in tup.1 {
res.push((tup.0, &self.values[*idx]));
}
}
return res;
}
pub fn first_key_value(&self) -> Option<(&K, &V)> {
if let Some(key) = self.keys.first() {
Some((key, &self.values[0]))
} else {
None
}
}
pub fn pop_first(&mut self) -> Option<(K, V)> {
if self.keys.is_empty() {
None
} else {
let key = self.keys.remove(0);
let value = self.values.remove(0);
self.i.remove(&key);
Some((key, value))
}
}
pub fn last_key_value(&self) -> Option<(&K, &V)> {
if let Some(key) = self.keys.last() {
Some((key, &self.values.last().unwrap()))
} else {
None
}
}
pub fn pop_last(&mut self) -> Option<(K, V)> {
if self.keys.is_empty() {
None
} else {
let key = self.keys.pop().unwrap();
let value = self.values.pop().unwrap();
self.i.remove(&key);
Some((key, value))
}
}
pub fn contains_key(&self, key: &K) -> bool {
self.i.get(key).is_some()
}
pub fn insert(&mut self, key: K, value: V) -> Option<&V> {
if let Some(indexes) = self.i.get_mut(&key) {
indexes.push(self.values.len());
} else {
self.i.insert(key.clone(), vec![self.values.len()]);
}
self.values.push(value);
self.keys.push(key);
return self.values.last();
}
pub fn insert_edge(&mut self, from: K, to: K) -> Option<(&K, &K)> {
self.edges.insert(from.clone(), to);
self.edges.get_key_value(&from)
}
pub fn len(&self) -> usize {
self.i.len()
}
pub fn is_empty(&self) -> bool {
self.i.len() == 0
}
pub fn index_copy(&self) -> BTreeMap<K, Vec<usize>> {
self.i.clone().into()
}
#[inline]
pub fn index(&self, key: K) -> Vec<&V> {
self.get(&key)
}
pub fn iter(&self) -> Iter<'_, K, V> {
Iter {
graph: &self,
length: self.len(),
}
}
}
#[derive(Debug, Clone)]
pub struct Iter<'a, K: 'a, V: 'a> {
graph: &'a IndexedGraph<K, V>,
length: usize,
}
impl<'a, K: Ord + Clone, V> IntoIterator for &'a IndexedGraph<K, V> {
type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V>;
fn into_iter(self) -> Iter<'a, K, V> {
self.iter()
}
}
impl<'a, K: 'a + Ord + Clone, V: 'a> Iterator for Iter<'a, K, V> {
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<(&'a K, &'a V)> {
if self.length == 0 {
None
} else {
self.length -= 1;
let idx = &self.graph.len() - 1 - self.length;
Some((&self.graph.keys[idx], &self.graph.values[idx]))
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.length, Some(self.length))
}
fn last(self) -> Option<(&'a K, &'a V)> {
self.graph.last_key_value()
}
fn min(mut self) -> Option<(&'a K, &'a V)> {
self.next()
}
fn max(self) -> Option<(&'a K, &'a V)> {
self.last()
}
}
impl<K: Ord + Clone, V> FusedIterator for Iter<'_, K, V> {}
impl<'a, K: 'a + Ord + Clone, V: 'a> DoubleEndedIterator for Iter<'a, K, V> {
fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
if self.length == 0 {
None
} else {
self.length -= 1;
let idx = self.length;
Some((&self.graph.keys[idx], &self.graph.values[idx]))
}
}
}
impl<K: Ord + Clone, V> ExactSizeIterator for Iter<'_, K, V> {
fn len(&self) -> usize {
self.length
}
}