use std::marker::PhantomData;
use crate::{BitMatrix, Index};
#[derive(Debug, Clone)]
pub struct IndexMultimap<K: Index, V: From<usize>> {
assocs: BitMatrix,
value_count: usize,
_idx_ty: PhantomData<fn(K, V)>,
}
impl<K: Index, V: From<usize>> IndexMultimap<K, V> {
pub fn get<'a>(&'a self, key: &K) -> impl Iterator<Item = V> + 'a {
let index = key.get();
let max_index = self.assocs.height(self.value_count);
(max_index > index)
.then(|| self.assocs.row(self.value_count, index).map(|i| V::from(i)))
.into_iter()
.flatten()
}
}
impl<K: Index, V: From<usize> + Index> FromIterator<(K, V)> for IndexMultimap<K, V> {
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
let mut max_value = 0;
let mut max_key = 0;
let key_values = iter
.into_iter()
.map(|(k, v)| {
max_key = max_key.max(k.get() + 1);
max_value = max_value.max(v.get() + 1);
(k, v)
})
.collect::<Box<[_]>>();
let (width, height) = (max_value, max_key);
let mut assocs = BitMatrix::new_with_size(width, height);
for (key, value) in &*key_values {
assocs.enable_bit(width, value.get(), key.get()).unwrap();
}
IndexMultimap { assocs, value_count: width, _idx_ty: PhantomData }
}
}