use std::borrow::Borrow;
use std::hash::{BuildHasher, Hash};
use indexmap::map::{IndexMap, OccupiedEntry as IMOccupiedEntry, VacantEntry as IMVacantEntry};
use crate::editable_binary_heap::HeapIndex;
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
pub(crate) struct MediatorIndex(pub(crate) usize);
#[derive(Clone, Debug)]
pub(crate) struct Mediator<TKey: Hash + Eq, S: BuildHasher> {
map: IndexMap<TKey, HeapIndex, S>,
}
#[inline(always)]
fn with_copied_heap_index<'a, T>((k, &i): (&'a T, &HeapIndex)) -> (&'a T, HeapIndex) {
(k, i)
}
pub(crate) struct VacantEntry<'a, TKey: 'a + Hash + Eq, S: BuildHasher> {
internal: IMVacantEntry<'a, TKey, HeapIndex>,
map: *mut Mediator<TKey, S>,
}
pub(crate) struct OccupiedEntry<'a, TKey: 'a + Hash + Eq, S: BuildHasher> {
internal: IMOccupiedEntry<'a, TKey, HeapIndex>,
map: *mut Mediator<TKey, S>,
}
pub(crate) enum MediatorEntry<'a, TKey: 'a + Hash + Eq, S: BuildHasher> {
Vacant(VacantEntry<'a, TKey, S>),
Occupied(OccupiedEntry<'a, TKey, S>),
}
impl<TKey, S> Mediator<TKey, S>
where
TKey: Hash + Eq,
S: BuildHasher,
{
pub(crate) fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
Self {
map: IndexMap::with_capacity_and_hasher(capacity, hasher),
}
}
#[inline(always)]
pub(crate) fn reserve(&mut self, additional: usize) {
self.map.reserve(additional)
}
#[inline(always)]
pub(crate) fn len(&self) -> usize {
self.map.len()
}
#[inline(always)]
pub(crate) fn is_empty(&self) -> bool {
self.map.is_empty()
}
#[inline(always)]
pub(crate) fn clear(&mut self) {
self.map.clear()
}
#[inline(always)]
pub(crate) fn get_index(&self, MediatorIndex(position): MediatorIndex) -> (&TKey, HeapIndex) {
self.map
.get_index(position)
.map(with_copied_heap_index)
.expect("All mediator indexes must be valid")
}
#[inline(always)]
pub(crate) fn entry(&mut self, key: TKey) -> MediatorEntry<TKey, S> {
let map = self as *mut _;
match self.map.entry(key) {
indexmap::map::Entry::Occupied(internal) => {
MediatorEntry::Occupied(OccupiedEntry { internal, map })
}
indexmap::map::Entry::Vacant(internal) => {
MediatorEntry::Vacant(VacantEntry { internal, map })
}
}
}
#[inline(always)]
pub(crate) fn get<Q>(&self, key: &Q) -> Option<HeapIndex>
where
TKey: Borrow<Q>,
Q: Hash + Eq + ?Sized,
{
self.map.get(key).copied()
}
#[inline(always)]
pub(crate) fn get_full<'a, Q>(&'a self, key: &Q) -> Option<(MediatorIndex, &'a TKey, HeapIndex)>
where
TKey: Borrow<Q>,
Q: Hash + Eq + ?Sized,
{
self.map
.get_full(key)
.map(|(idx, key, &val)| (MediatorIndex(idx), key, val))
}
#[inline(always)]
pub(crate) fn swap_remove_index(
&mut self,
MediatorIndex(index): MediatorIndex,
) -> (TKey, HeapIndex) {
self.map
.swap_remove_index(index)
.expect("All mediator indexes must be valid")
}
#[inline(always)]
pub(crate) fn get_index_mut(&mut self, MediatorIndex(index): MediatorIndex) -> &mut HeapIndex {
self.map
.get_index_mut(index)
.expect("All mediator indexes must be valid")
.1
}
#[cfg(test)]
pub(crate) fn iter(&self) -> impl Iterator<Item = (&TKey, HeapIndex)> {
self.map.iter().map(with_copied_heap_index)
}
}
impl<'a, TKey: 'a + Hash + Eq, S: BuildHasher> VacantEntry<'a, TKey, S> {
#[inline]
pub(crate) unsafe fn insert(
self,
value: HeapIndex,
) -> (&'a mut Mediator<TKey, S>, MediatorIndex) {
let map = self.map;
let result_index = MediatorIndex(self.internal.index());
{
self.internal.insert(value);
}
let mediator = map.as_mut().expect("Validated in entry method");
(mediator, result_index)
}
#[inline]
pub(crate) fn get_key(&self) -> &TKey {
self.internal.key()
}
#[inline]
pub(crate) fn index(&self) -> MediatorIndex {
MediatorIndex(self.internal.index())
}
}
impl<'a, TKey: 'a + Hash + Eq, S: BuildHasher> OccupiedEntry<'a, TKey, S> {
#[inline]
pub(crate) fn get_heap_idx(&self) -> HeapIndex {
*self.internal.get()
}
#[inline]
pub(crate) fn get_key(&self) -> &TKey {
self.internal.key()
}
#[inline]
pub(crate) unsafe fn transform_to_map(self) -> &'a mut Mediator<TKey, S> {
let map = self.map;
std::mem::drop(self);
let mediator = map.as_mut().expect("Validated in entry method");
mediator
}
}