use core::hash::Hash;
pub use entry::{Entry, OccupiedEntry, VacantEntry};
pub use iter::Iter;
use std::borrow::Borrow;
use std::fmt::Debug;
use std::collections::HashMap;
pub mod entry;
pub mod iter;
#[cfg(test)]
mod tests;
#[derive(Hash, PartialEq, Eq, Clone, Copy)]
struct Index(u128);
#[derive(Clone)]
pub struct MultiKeyMap<K, V>
where
K: Hash + Eq,
{
keys: HashMap<K, Index>,
data: HashMap<Index, (usize, V)>,
max_index: Index,
}
impl<K, V> Default for MultiKeyMap<K, V>
where
K: Hash + Eq,
{
fn default() -> Self {
MultiKeyMap {
keys: HashMap::new(),
data: HashMap::new(),
max_index: Index(0),
}
}
}
#[allow(dead_code)]
impl<K, V> MultiKeyMap<K, V>
where
K: Hash + Eq,
{
pub fn new() -> Self {
Default::default()
}
pub(crate) fn next_index(&mut self) -> Index {
let idx = self.max_index;
self.max_index = Index(self.max_index.0 + 1);
idx
}
pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.keys.contains_key(k)
}
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
if self.contains_key(&k) {
let idx = self.keys.get(&k).unwrap();
let (count, _) = self.data.get_mut(idx).unwrap();
if *count <= 1 {
self.data.insert(*idx, (1, v)).map(|(_, v)| v)
} else {
*count -= 1;
let new_idx = self.max_index;
self.max_index = Index(self.max_index.0 + 1);
self.keys.insert(k, new_idx);
self.data.insert(new_idx, (1, v));
None
}
} else {
let new_idx = self.max_index;
self.max_index = Index(self.max_index.0 + 1);
self.keys.insert(k, new_idx);
self.data.insert(new_idx, (1, v));
None
}
}
pub fn alias<Q: ?Sized>(&mut self, k: &Q, alias: K) -> Result<&mut V, K>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
if self.contains_key(k) {
let idx = *self.keys.get(k).unwrap();
let (count, v) = self.data.get_mut(&idx).unwrap();
*count += 1;
self.keys.insert(alias, idx);
Ok(v)
} else {
Err(alias)
}
}
pub fn alias_many<Q: ?Sized>(&mut self, k: &Q, aliases: Vec<K>) -> Result<&mut V, Vec<K>>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
if self.contains_key(k) {
let idx = *self.keys.get(k).unwrap();
let (count, v) = self.data.get_mut(&idx).unwrap();
for alias in aliases {
*count += 1;
self.keys.insert(alias, idx);
}
Ok(v)
} else {
Err(aliases)
}
}
pub fn keys(&self) -> impl Iterator<Item = &K> {
self.keys.keys()
}
pub fn values(&self) -> impl Iterator<Item = &V> {
self.data.values().map(|(_, v)| v)
}
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
self.data.values_mut().map(|(_, v)| v)
}
pub fn into_keys(self) -> impl Iterator<Item = K> {
self.keys.into_keys()
}
pub fn into_values(self) -> impl Iterator<Item = V> {
self.data.into_values().map(|(_, v)| v)
}
pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
iter::Iter::new(self)
}
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.keys
.get(k)
.and_then(|idx| self.data.get(idx))
.map(|(_, v)| v)
}
pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.keys
.get(k)
.and_then(|idx| self.data.get_mut(idx))
.map(|(_, v)| v)
}
pub fn insert_many(&mut self, ks: Vec<K>, v: V) -> Vec<V> {
let mut bumped = vec![];
let new_idx = self.max_index;
self.max_index = Index(self.max_index.0 + 1);
let mut new_count = 0;
for k in ks {
if self.contains_key(&k) {
let idx = self.keys.get(&k).unwrap();
let (count, _) = self.data.get_mut(idx).unwrap();
if *count <= 1 {
if let Some((_, v)) = self.data.remove(idx) {
bumped.push(v);
}
} else {
*count -= 1;
new_count += 1;
self.keys.insert(k, new_idx);
}
} else {
new_count += 1;
self.keys.insert(k, new_idx);
}
}
self.data.insert(new_idx, (new_count, v));
bumped
}
pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
if self.contains_key(k) {
let idx = self.keys.get(k).unwrap();
let (count, _) = self.data.get_mut(idx).unwrap();
if *count == 1 {
let result = self.data.remove(idx).map(|(_, v)| v);
self.keys.remove(k);
result
} else {
*count -= 1;
self.keys.remove(k);
None
}
} else {
None
}
}
pub fn remove_many<Q: ?Sized, const N: usize>(&mut self, ks: [&Q; N]) -> Vec<V>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
let mut bumped = vec![];
for k in ks {
if let Some(v) = self.remove(k) {
bumped.push(v);
}
}
bumped
}
pub fn entry(&mut self, k: K) -> Entry<K, V> {
if let Some(idx) = self.keys.get(&k) {
Entry::Occupied(OccupiedEntry {
key: k,
idx: *idx,
map: self,
})
} else {
Entry::Vacant(VacantEntry { key: k, map: self })
}
}
}
impl<K, V, const N: usize> From<[(Vec<K>, V); N]> for MultiKeyMap<K, V>
where
K: Hash + Eq,
{
fn from(arr: [(Vec<K>, V); N]) -> Self {
Self::from_iter(arr)
}
}
impl<K, V> FromIterator<(Vec<K>, V)> for MultiKeyMap<K, V>
where
K: Hash + Eq,
{
fn from_iter<T: IntoIterator<Item = (Vec<K>, V)>>(iter: T) -> Self {
let mut map = Self::new();
for (keys, value) in iter {
map.insert_many(keys, value);
}
map
}
}
impl<K, V> PartialEq for MultiKeyMap<K, V>
where
K: Hash + Eq,
V: PartialEq,
{
fn eq(&self, rhs: &Self) -> bool {
if self.keys.len() != rhs.keys.len() || self.data.len() != rhs.data.len() {
return false;
}
self.iter()
.all(|(key, value)| rhs.get(key).map_or(false, |v| *value == *v))
}
}
impl<K, V> Eq for MultiKeyMap<K, V>
where
K: Hash + Eq,
V: Eq,
{
}
impl<K, V> Debug for MultiKeyMap<K, V>
where
K: Hash + Eq + Debug,
V: Debug
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_map().entries(self.iter()).finish()
}
}
impl<'a, K, V> Extend<(&'a [K], &'a V)> for MultiKeyMap<K, V>
where
K: Hash + Eq + Copy,
V: Copy,
{
fn extend<T: IntoIterator<Item = (&'a [K], &'a V)>>(&mut self, iter: T) {
for (ks, v) in iter {
self.insert_many(ks.to_vec(), *v);
}
}
}
impl<K, V> Extend<(Vec<K>, V)> for MultiKeyMap<K, V>
where
K: Hash + Eq,
{
fn extend<T: IntoIterator<Item = (Vec<K>, V)>>(&mut self, iter: T) {
for (ks, v) in iter {
self.insert_many(ks, v);
}
}
}