use crate::entry::{Entry, OccupiedEntry, VacantEntry};
use crate::hash::RobinHoodKey;
use crate::iter::{Drain, Iter, IterMut, Keys, Values};
use crate::sync::{MutexGuard, SpinMutex};
use crate::table::RawTable;
pub struct RobinHoodMap<K, V> {
table: SpinMutex<RawTable<K, V>>,
}
impl<K: RobinHoodKey + PartialEq, V> RobinHoodMap<K, V> {
#[inline]
#[must_use]
pub fn new() -> Self {
Self {
table: SpinMutex::new(RawTable::new()),
}
}
#[inline]
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self {
table: SpinMutex::new(RawTable::with_capacity(capacity)),
}
}
#[inline]
pub fn len(&self) -> usize {
self.table.lock().size()
}
#[inline]
pub fn capacity(&self) -> usize {
self.table.lock().capacity()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.table.lock().is_empty()
}
#[inline]
pub fn with_key<F, R>(&self, key: &K, f: F) -> Option<R>
where
F: FnOnce(&V) -> R,
{
let guard = self.table.lock();
guard.get(key).map(f)
}
#[inline]
pub fn with_key_mut<F, R>(&self, key: &K, f: F) -> Option<R>
where
F: FnOnce(&mut V) -> R,
{
let mut guard = self.table.lock();
guard.get_mut(key).map(f)
}
#[inline]
pub fn read(&self) -> MutexGuard<'_, RawTable<K, V>> {
self.table.lock()
}
#[inline]
#[must_use]
pub fn insert(&self, key: K, value: V) -> bool {
self.table.lock().insert(key, value)
}
#[inline]
#[must_use]
pub fn remove(&self, key: &K) -> bool {
self.table.lock().remove(key)
}
#[inline]
pub fn clear(&self) {
self.table.lock().clear();
}
#[inline]
pub fn reserve(&self, additional: usize) {
self.table.lock().reserve(additional);
}
#[inline]
pub fn entry(&self, key: K) -> Entry<'_, K, V>
where
K: Clone,
{
let guard = self.table.lock();
if guard.get(&key).is_some() {
Entry::Occupied(OccupiedEntry::new(guard, key))
} else {
Entry::Vacant(VacantEntry::new(guard, key))
}
}
#[inline]
pub fn iter(&self) -> Iter<'_, K, V> {
Iter::new(self.table.lock())
}
#[inline]
pub fn iter_mut(&self) -> IterMut<'_, K, V> {
IterMut::new(self.table.lock())
}
#[inline]
pub fn keys(&self) -> Keys<'_, K, V> {
Keys::new(self.table.lock())
}
#[inline]
pub fn values(&self) -> Values<'_, K, V> {
Values::new(self.table.lock())
}
#[inline]
pub fn drain(&self) -> Drain<'_, K, V> {
Drain::new(self.table.lock())
}
}
impl<'a, K: RobinHoodKey + PartialEq, V> IntoIterator for &'a RobinHoodMap<K, V> {
type Item = (&'a K, &'a V);
type IntoIter = crate::iter::Iter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}