use std::{
collections::hash_map,
ops::{Index, IndexMut},
};
use ahash::AHashMap;
use index_vec::{Idx, IndexVec};
use crate::{
pointer::{ArcFamily, PointerFamily, RcFamily, RefFamily},
FromIndexicalIterator, IndexedDomain, IndexedValue, ToIndex,
};
pub struct SparseIndexMap<'a, K: IndexedValue + 'a, V, P: PointerFamily<'a>> {
map: AHashMap<K::Index, V>,
domain: P::Pointer<IndexedDomain<K>>,
}
pub type SparseRcIndexMap<'a, K, V> = SparseIndexMap<'a, K, V, RcFamily>;
pub type SparseArcIndexMap<'a, K, V> = SparseIndexMap<'a, K, V, ArcFamily>;
pub type SparseRefIndexMap<'a, K, V> = SparseIndexMap<'a, K, V, RefFamily<'a>>;
impl<'a, K, V, P> SparseIndexMap<'a, K, V, P>
where
K: IndexedValue + 'a,
P: PointerFamily<'a>,
{
pub fn new(domain: &P::Pointer<IndexedDomain<K>>) -> Self {
SparseIndexMap {
map: AHashMap::default(),
domain: domain.clone(),
}
}
#[inline]
pub fn get<M>(&self, key: impl ToIndex<K, M>) -> Option<&V> {
let idx = key.to_index(&self.domain);
self.map.get(&idx)
}
#[inline]
pub fn get_mut<M>(&mut self, key: impl ToIndex<K, M>) -> Option<&mut V> {
let idx = key.to_index(&self.domain);
self.map.get_mut(&idx)
}
#[inline]
pub unsafe fn get_unchecked<M>(&self, key: impl ToIndex<K, M>) -> &V {
let idx = key.to_index(&self.domain);
self.map.get(&idx).unwrap_unchecked()
}
#[inline]
pub unsafe fn get_unchecked_mut<M>(&mut self, key: impl ToIndex<K, M>) -> &mut V {
let idx = key.to_index(&self.domain);
self.map.get_mut(&idx).unwrap_unchecked()
}
#[inline]
pub fn insert<M>(&mut self, key: impl ToIndex<K, M>, value: V) {
let idx = key.to_index(&self.domain);
self.map.insert(idx, value);
}
#[inline]
pub fn values(&self) -> impl Iterator<Item = &V> + '_ {
self.map.values()
}
#[inline]
pub fn entry<M>(&mut self, key: impl ToIndex<K, M>) -> hash_map::Entry<'_, K::Index, V> {
let idx = key.to_index(&self.domain);
self.map.entry(idx)
}
#[inline]
pub fn len(&self) -> usize {
self.map.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
}
impl<'a, K, V, P> Index<K::Index> for SparseIndexMap<'a, K, V, P>
where
K: IndexedValue + 'a,
P: PointerFamily<'a>,
{
type Output = V;
fn index(&self, index: K::Index) -> &Self::Output {
self.get(index).unwrap()
}
}
impl<'a, K, V, P> IndexMut<K::Index> for SparseIndexMap<'a, K, V, P>
where
K: IndexedValue + 'a,
P: PointerFamily<'a>,
{
fn index_mut(&mut self, index: K::Index) -> &mut Self::Output {
self.get_mut(index).unwrap()
}
}
impl<'a, K, V, P, M, U> FromIndexicalIterator<'a, K, P, M, (U, V)> for SparseIndexMap<'a, K, V, P>
where
K: IndexedValue + 'a,
P: PointerFamily<'a>,
U: ToIndex<K, M>,
{
fn from_indexical_iter(
iter: impl Iterator<Item = (U, V)>,
domain: &P::Pointer<IndexedDomain<K>>,
) -> Self {
let map = iter
.map(|(u, v)| (u.to_index(domain), v))
.collect::<AHashMap<_, _>>();
SparseIndexMap {
map,
domain: domain.clone(),
}
}
}
impl<'a, 'b, K, V, P> IntoIterator for &'b SparseIndexMap<'a, K, V, P>
where
K: IndexedValue + 'a + 'b,
V: 'b,
P: PointerFamily<'a>,
{
type Item = (&'b K::Index, &'b V);
type IntoIter = hash_map::Iter<'b, K::Index, V>;
fn into_iter(self) -> Self::IntoIter {
self.map.iter()
}
}
pub struct DenseIndexMap<'a, K: IndexedValue + 'a, V, P: PointerFamily<'a>> {
map: IndexVec<K::Index, V>,
domain: P::Pointer<IndexedDomain<K>>,
}
pub type DenseRcIndexMap<'a, K, V> = DenseIndexMap<'a, K, V, RcFamily>;
pub type DenseArcIndexMap<'a, K, V> = DenseIndexMap<'a, K, V, ArcFamily>;
pub type DenseRefIndexMap<'a, K, V> = DenseIndexMap<'a, K, V, RefFamily<'a>>;
impl<'a, K, V, P> DenseIndexMap<'a, K, V, P>
where
K: IndexedValue + 'a,
P: PointerFamily<'a>,
{
#[inline]
pub fn new(domain: &P::Pointer<IndexedDomain<K>>, mk_elem: impl FnMut(K::Index) -> V) -> Self {
Self::from_vec(domain, IndexVec::from_iter(domain.indices().map(mk_elem)))
}
#[inline]
fn from_vec(domain: &P::Pointer<IndexedDomain<K>>, map: IndexVec<K::Index, V>) -> Self {
DenseIndexMap {
map,
domain: domain.clone(),
}
}
#[inline]
pub fn get<M>(&self, idx: impl ToIndex<K, M>) -> Option<&V> {
let idx = idx.to_index(&self.domain);
self.map.get(idx)
}
#[inline]
pub fn get_mut<M>(&mut self, idx: impl ToIndex<K, M>) -> Option<&mut V> {
let idx = idx.to_index(&self.domain);
self.map.get_mut(idx)
}
#[inline]
pub unsafe fn get_unchecked<M>(&self, idx: impl ToIndex<K, M>) -> &V {
let idx = idx.to_index(&self.domain);
self.map.raw.get_unchecked(idx.index())
}
#[inline]
pub unsafe fn get_unchecked_mut<M>(&mut self, idx: impl ToIndex<K, M>) -> &mut V {
let idx = idx.to_index(&self.domain);
self.map.raw.get_unchecked_mut(idx.index())
}
#[inline]
pub fn insert<M>(&mut self, idx: impl ToIndex<K, M>, value: V) {
let idx = idx.to_index(&self.domain);
self.map[idx] = value;
}
#[inline]
pub fn values(&self) -> impl Iterator<Item = &V> + '_ {
self.map.iter()
}
}
impl<'a, K, V, P> Index<K::Index> for DenseIndexMap<'a, K, V, P>
where
K: IndexedValue + 'a,
P: PointerFamily<'a>,
{
type Output = V;
#[inline]
fn index(&self, index: K::Index) -> &Self::Output {
self.get(index).unwrap()
}
}
impl<'a, K, V, P> IndexMut<K::Index> for DenseIndexMap<'a, K, V, P>
where
K: IndexedValue + 'a,
P: PointerFamily<'a>,
{
#[inline]
fn index_mut(&mut self, index: K::Index) -> &mut Self::Output {
self.get_mut(index).unwrap()
}
}
impl<'a, K, V, P, M, U> FromIndexicalIterator<'a, K, P, M, (U, V)> for DenseIndexMap<'a, K, V, P>
where
K: IndexedValue + 'a,
P: PointerFamily<'a>,
U: ToIndex<K, M>,
{
fn from_indexical_iter(
iter: impl Iterator<Item = (U, V)>,
domain: &P::Pointer<IndexedDomain<K>>,
) -> Self {
let mut map = iter
.map(|(u, v)| (u.to_index(domain), v))
.collect::<AHashMap<_, _>>();
let vec = domain
.indices()
.map(|i| map.remove(&i).unwrap_or_else(|| panic!("Cannot use FromIndexicalIterator for a DenseIndexMap with a sparse key set")))
.collect::<IndexVec<_, _>>();
DenseIndexMap::from_vec(domain, vec)
}
}