use derive_where::derive_where;
use index_list::{Index, IndexList};
use std::borrow::Borrow;
use std::collections::HashMap;
use std::hash::Hash;
use std::mem;
pub mod entry;
pub use crate::entry::{Entry, OccupiedEntry, VacantEntry};
#[derive_where(Default)]
pub struct OrderedHashMap<K, V> {
map: HashMap<K, Index>,
order: IndexList<(K, V)>,
}
impl<K, V> OrderedHashMap<K, V> {
pub fn new() -> Self {
Self {
map: HashMap::new(),
order: IndexList::new(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
map: HashMap::with_capacity(capacity),
order: IndexList::with_capacity(capacity),
}
}
pub fn len(&self) -> usize {
let Self { map, order } = self;
assert_eq!(map.len(), order.len());
order.len()
}
pub fn capacity(&self) -> usize {
let Self { map, order } = self;
map.capacity().min(order.capacity())
}
pub fn is_empty(&self) -> bool {
let Self { map, order } = self;
assert_eq!(map.is_empty(), order.is_empty());
order.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
self.order.iter().map(|(k, v)| (k, v))
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
self.order.iter_mut().map(|(k, v)| (&*k, v))
}
#[deprecated(note = "use `iter_mut` instead")]
pub fn for_each_mut(&mut self, mut f: impl FnMut(&K, &mut V)) {
let mut index = self.order.first_index();
while let Some((k, v)) = self.order.get_mut(index) {
f(k, v);
index = self.order.next_index(index);
}
}
pub fn keys(&self) -> impl Iterator<Item = &K> {
self.iter().map(|(k, _)| k)
}
pub fn values(&self) -> impl Iterator<Item = &V> {
self.iter().map(|(_, v)| v)
}
}
impl<K: Eq + Hash, V> OrderedHashMap<K, V> {
pub fn insert(&mut self, key: K, value: V) -> Option<V>
where
K: Clone,
{
match self.entry(key) {
Entry::Occupied(occupied_entry) => {
let old = mem::replace(occupied_entry.into_mut(), value);
Some(old)
}
Entry::Vacant(vacant_entry) => {
vacant_entry.insert(value);
None
}
}
}
pub fn get<Q: Eq + Hash + ?Sized>(&self, key: &Q) -> Option<&V>
where
K: Borrow<Q>,
{
let Self { map, order } = self;
let &idx = map.get(key)?;
let (k, v) = order.get(idx).unwrap();
debug_assert!(*k.borrow() == *key);
Some(v)
}
pub fn get_mut<Q: Eq + Hash + ?Sized>(&mut self, key: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
{
let Self { map, order } = self;
let &idx = map.get(key)?;
let (k, v) = order.get_mut(idx).unwrap();
debug_assert!(*(*k).borrow() == *key);
Some(v)
}
pub fn contains_key<Q: Eq + Hash + ?Sized>(&self, key: &Q) -> bool
where
K: Borrow<Q>,
{
self.map.contains_key(key)
}
pub fn remove<Q: Eq + Hash + ?Sized>(&mut self, key: &Q) -> Option<V>
where
K: Borrow<Q>,
{
self.remove_entry(key).map(|(_, v)| v)
}
pub fn remove_entry<Q: Eq + Hash + ?Sized>(&mut self, key: &Q) -> Option<(K, V)>
where
K: Borrow<Q>,
{
let Self { map, order } = self;
let idx = map.remove(key)?;
let (k_stored, v) = order.remove(idx).unwrap();
debug_assert!(*k_stored.borrow() == *key);
Some((k_stored, v))
}
pub fn pop_front(&mut self) -> Option<(K, V)> {
let Self { map, order } = self;
let (k, v) = order.remove_first()?;
map.remove(&k).unwrap();
Some((k, v))
}
pub fn pop_back(&mut self) -> Option<(K, V)> {
let Self { map, order } = self;
let (k, v) = order.remove_last()?;
map.remove(&k).unwrap();
Some((k, v))
}
pub fn clear(&mut self) {
let Self { map, order } = self;
map.clear();
order.clear();
}
pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
let Self { map, order } = self;
let std_entry = map.entry(key);
Entry::new(std_entry, order)
}
pub fn shrink_to(&mut self, min_capacity: usize) {
let len = self.len();
let Self { map, order } = self;
map.shrink_to(min_capacity);
let min_capacity = min_capacity.max(len);
if min_capacity >= order.capacity() {
return;
}
let mut new_order = IndexList::with_capacity(min_capacity);
for (k, v) in order.drain_iter() {
let ind = new_order.insert_last((k, v));
let k = &new_order.get(ind).unwrap().0;
*map.get_mut(k).unwrap() = ind;
}
*order = new_order;
}
pub fn shrink_to_fit(&mut self) {
self.shrink_to(0);
}
}