use crate::raw::utils::MapGuard;
use crate::raw::{self, InsertResult};
use crate::Equivalent;
use seize::{Collector, Guard, LocalGuard, OwnedGuard};
use std::collections::hash_map::RandomState;
use std::fmt;
use std::hash::{BuildHasher, Hash};
use std::marker::PhantomData;
pub struct HashMap<K, V, S = RandomState> {
raw: raw::HashMap<K, V, S>,
}
unsafe impl<K: Send, V: Send, S: Send> Send for HashMap<K, V, S> {}
unsafe impl<K: Send + Sync, V: Send + Sync, S: Sync> Sync for HashMap<K, V, S> {}
pub struct HashMapBuilder<K, V, S = RandomState> {
hasher: S,
capacity: usize,
collector: Collector,
resize_mode: ResizeMode,
_kv: PhantomData<(K, V)>,
}
impl<K, V> HashMapBuilder<K, V> {
pub fn hasher<S>(self, hasher: S) -> HashMapBuilder<K, V, S> {
HashMapBuilder {
hasher,
capacity: self.capacity,
collector: self.collector,
resize_mode: self.resize_mode,
_kv: PhantomData,
}
}
}
impl<K, V, S> HashMapBuilder<K, V, S> {
pub fn capacity(self, capacity: usize) -> HashMapBuilder<K, V, S> {
HashMapBuilder {
capacity,
hasher: self.hasher,
collector: self.collector,
resize_mode: self.resize_mode,
_kv: PhantomData,
}
}
pub fn resize_mode(self, resize_mode: ResizeMode) -> Self {
HashMapBuilder {
resize_mode,
hasher: self.hasher,
capacity: self.capacity,
collector: self.collector,
_kv: PhantomData,
}
}
pub fn collector(self, collector: Collector) -> Self {
HashMapBuilder {
collector,
hasher: self.hasher,
capacity: self.capacity,
resize_mode: self.resize_mode,
_kv: PhantomData,
}
}
pub fn build(self) -> HashMap<K, V, S> {
HashMap {
raw: raw::HashMap::new(self.capacity, self.hasher, self.collector, self.resize_mode),
}
}
}
impl<K, V, S> fmt::Debug for HashMapBuilder<K, V, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("HashMapBuilder")
.field("capacity", &self.capacity)
.field("collector", &self.collector)
.field("resize_mode", &self.resize_mode)
.finish()
}
}
#[derive(Debug)]
pub enum ResizeMode {
Incremental(usize),
Blocking,
}
impl Default for ResizeMode {
fn default() -> Self {
ResizeMode::Incremental(64)
}
}
impl<K, V> HashMap<K, V> {
pub fn new() -> HashMap<K, V> {
HashMap::with_capacity_and_hasher(0, RandomState::new())
}
pub fn with_capacity(capacity: usize) -> HashMap<K, V> {
HashMap::with_capacity_and_hasher(capacity, RandomState::new())
}
pub fn builder() -> HashMapBuilder<K, V> {
HashMapBuilder {
capacity: 0,
hasher: RandomState::default(),
collector: Collector::new(),
resize_mode: ResizeMode::default(),
_kv: PhantomData,
}
}
}
impl<K, V, S> Default for HashMap<K, V, S>
where
S: Default,
{
fn default() -> Self {
HashMap::with_hasher(S::default())
}
}
impl<K, V, S> HashMap<K, V, S> {
pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
HashMap::with_capacity_and_hasher(0, hash_builder)
}
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K, V, S> {
HashMap {
raw: raw::HashMap::new(
capacity,
hash_builder,
Collector::default(),
ResizeMode::default(),
),
}
}
#[inline]
pub fn pin(&self) -> HashMapRef<'_, K, V, S, LocalGuard<'_>> {
HashMapRef {
guard: self.raw.guard(),
map: self,
}
}
#[inline]
pub fn pin_owned(&self) -> HashMapRef<'_, K, V, S, OwnedGuard<'_>> {
HashMapRef {
guard: self.raw.owned_guard(),
map: self,
}
}
#[inline]
pub fn guard(&self) -> LocalGuard<'_> {
self.raw.collector().enter()
}
#[inline]
pub fn owned_guard(&self) -> OwnedGuard<'_> {
self.raw.collector().enter_owned()
}
}
impl<K, V, S> HashMap<K, V, S>
where
K: Hash + Eq,
S: BuildHasher,
{
#[inline]
pub fn len(&self) -> usize {
self.raw.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn contains_key<Q>(&self, key: &Q, guard: &impl Guard) -> bool
where
Q: Equivalent<K> + Hash + ?Sized,
{
self.get(key, self.raw.verify(guard)).is_some()
}
#[inline]
pub fn get<'g, Q>(&self, key: &Q, guard: &'g impl Guard) -> Option<&'g V>
where
K: 'g,
Q: Equivalent<K> + Hash + ?Sized,
{
match self.raw.get(key, self.raw.verify(guard)) {
Some((_, v)) => Some(v),
None => None,
}
}
#[inline]
pub fn get_key_value<'g, Q>(&self, key: &Q, guard: &'g impl Guard) -> Option<(&'g K, &'g V)>
where
Q: Equivalent<K> + Hash + ?Sized,
{
self.raw.get(key, self.raw.verify(guard))
}
#[inline]
pub fn insert<'g>(&self, key: K, value: V, guard: &'g impl Guard) -> Option<&'g V> {
match self.raw.insert(key, value, true, self.raw.verify(guard)) {
InsertResult::Inserted(_) => None,
InsertResult::Replaced(value) => Some(value),
InsertResult::Error { .. } => unreachable!(),
}
}
#[inline]
pub fn try_insert<'g>(
&self,
key: K,
value: V,
guard: &'g impl Guard,
) -> Result<&'g V, OccupiedError<'g, V>> {
match self.raw.insert(key, value, false, self.raw.verify(guard)) {
InsertResult::Inserted(value) => Ok(value),
InsertResult::Error {
current,
not_inserted,
} => Err(OccupiedError {
current,
not_inserted,
}),
InsertResult::Replaced(_) => unreachable!(),
}
}
#[inline]
pub fn try_insert_with<'g, F>(
&self,
key: K,
f: F,
guard: &'g impl Guard,
) -> Result<&'g V, &'g V>
where
F: FnOnce() -> V,
K: 'g,
{
self.raw.try_insert_with(key, f, self.raw.verify(guard))
}
#[inline]
pub fn get_or_insert<'g>(&self, key: K, value: V, guard: &'g impl Guard) -> &'g V {
match self.try_insert(key, value, guard) {
Ok(inserted) => inserted,
Err(OccupiedError { current, .. }) => current,
}
}
#[inline]
pub fn get_or_insert_with<'g, F>(&self, key: K, f: F, guard: &'g impl Guard) -> &'g V
where
F: FnOnce() -> V,
K: 'g,
{
self.raw.get_or_insert_with(key, f, self.raw.verify(guard))
}
#[inline]
pub fn update<'g, F>(&self, key: K, update: F, guard: &'g impl Guard) -> Option<&'g V>
where
F: Fn(&V) -> V,
K: 'g,
{
self.raw.update(key, update, self.raw.verify(guard))
}
#[inline]
pub fn update_or_insert<'g, F>(
&self,
key: K,
update: F,
value: V,
guard: &'g impl Guard,
) -> &'g V
where
F: Fn(&V) -> V,
K: 'g,
{
self.update_or_insert_with(key, update, || value, guard)
}
#[inline]
pub fn update_or_insert_with<'g, U, F>(
&self,
key: K,
update: U,
f: F,
guard: &'g impl Guard,
) -> &'g V
where
F: FnOnce() -> V,
U: Fn(&V) -> V,
K: 'g,
{
self.raw
.update_or_insert_with(key, update, f, self.raw.verify(guard))
}
#[inline]
pub fn compute<'g, F, T>(
&self,
key: K,
compute: F,
guard: &'g impl Guard,
) -> Compute<'g, K, V, T>
where
F: FnMut(Option<(&'g K, &'g V)>) -> Operation<V, T>,
{
self.raw.compute(key, compute, self.raw.verify(guard))
}
#[inline]
pub fn remove<'g, Q>(&self, key: &Q, guard: &'g impl Guard) -> Option<&'g V>
where
K: 'g,
Q: Equivalent<K> + Hash + ?Sized,
{
match self.raw.remove(key, self.raw.verify(guard)) {
Some((_, value)) => Some(value),
None => None,
}
}
#[inline]
pub fn remove_entry<'g, Q>(&self, key: &Q, guard: &'g impl Guard) -> Option<(&'g K, &'g V)>
where
K: 'g,
Q: Equivalent<K> + Hash + ?Sized,
{
self.raw.remove(key, self.raw.verify(guard))
}
#[inline]
pub fn remove_if<'g, Q, F>(
&self,
key: &Q,
should_remove: F,
guard: &'g impl Guard,
) -> Result<Option<(&'g K, &'g V)>, (&'g K, &'g V)>
where
Q: Equivalent<K> + Hash + ?Sized,
F: FnMut(&K, &V) -> bool,
{
self.raw
.remove_if(key, should_remove, self.raw.verify(guard))
}
#[inline]
pub fn reserve(&self, additional: usize, guard: &impl Guard) {
self.raw.reserve(additional, self.raw.verify(guard))
}
#[inline]
pub fn clear(&self, guard: &impl Guard) {
self.raw.clear(self.raw.verify(guard))
}
#[inline]
pub fn retain<F>(&self, f: F, guard: &impl Guard)
where
F: FnMut(&K, &V) -> bool,
{
self.raw.retain(f, self.raw.verify(guard))
}
#[inline]
pub fn iter<'g, G>(&self, guard: &'g G) -> Iter<'g, K, V, G>
where
G: Guard,
{
Iter {
raw: self.raw.iter(self.raw.verify(guard)),
}
}
#[inline]
pub fn keys<'g, G>(&self, guard: &'g G) -> Keys<'g, K, V, G>
where
G: Guard,
{
Keys {
iter: self.iter(guard),
}
}
#[inline]
pub fn values<'g, G>(&self, guard: &'g G) -> Values<'g, K, V, G>
where
G: Guard,
{
Values {
iter: self.iter(guard),
}
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum Operation<V, T> {
Insert(V),
Remove,
Abort(T),
}
#[derive(Debug, PartialEq, Eq)]
pub enum Compute<'g, K, V, T> {
Inserted(&'g K, &'g V),
Updated {
old: (&'g K, &'g V),
new: (&'g K, &'g V),
},
Removed(&'g K, &'g V),
Aborted(T),
}
#[derive(Debug, PartialEq, Eq)]
pub struct OccupiedError<'a, V: 'a> {
pub current: &'a V,
pub not_inserted: V,
}
impl<K, V, S> PartialEq for HashMap<K, V, S>
where
K: Hash + Eq,
V: PartialEq,
S: BuildHasher,
{
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false;
}
let (guard1, guard2) = (&self.guard(), &other.guard());
let mut iter = self.iter(guard1);
iter.all(|(key, value)| other.get(key, guard2).is_some_and(|v| *value == *v))
}
}
impl<K, V, S> Eq for HashMap<K, V, S>
where
K: Hash + Eq,
V: Eq,
S: BuildHasher,
{
}
impl<K, V, S> fmt::Debug for HashMap<K, V, S>
where
K: Hash + Eq + fmt::Debug,
V: fmt::Debug,
S: BuildHasher,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let guard = self.guard();
f.debug_map().entries(self.iter(&guard)).finish()
}
}
impl<K, V, S> Extend<(K, V)> for &HashMap<K, V, S>
where
K: Hash + Eq,
S: BuildHasher,
{
fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
let iter = iter.into_iter();
let reserve = if self.is_empty() {
iter.size_hint().0
} else {
(iter.size_hint().0 + 1) / 2
};
let guard = self.guard();
self.reserve(reserve, &guard);
for (key, value) in iter {
self.insert(key, value, &guard);
}
}
}
impl<'a, K, V, S> Extend<(&'a K, &'a V)> for &HashMap<K, V, S>
where
K: Copy + Hash + Eq,
V: Copy,
S: BuildHasher,
{
fn extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) {
self.extend(iter.into_iter().map(|(&key, &value)| (key, value)));
}
}
impl<K, V, const N: usize> From<[(K, V); N]> for HashMap<K, V, RandomState>
where
K: Hash + Eq,
{
fn from(arr: [(K, V); N]) -> Self {
HashMap::from_iter(arr)
}
}
impl<K, V, S> FromIterator<(K, V)> for HashMap<K, V, S>
where
K: Hash + Eq,
S: BuildHasher + Default,
{
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
let mut iter = iter.into_iter();
if let Some((key, value)) = iter.next() {
let (lower, _) = iter.size_hint();
let map = HashMap::with_capacity_and_hasher(lower.saturating_add(1), S::default());
{
let map = map.pin();
map.insert(key, value);
for (key, value) in iter {
map.insert(key, value);
}
}
map
} else {
Self::default()
}
}
}
impl<K, V, S> Clone for HashMap<K, V, S>
where
K: Clone + Hash + Eq,
V: Clone,
S: BuildHasher + Clone,
{
fn clone(&self) -> HashMap<K, V, S> {
let other = HashMap::builder()
.capacity(self.len())
.hasher(self.raw.hasher.clone())
.collector(seize::Collector::new())
.build();
{
let (guard1, guard2) = (&self.guard(), &other.guard());
for (key, value) in self.iter(guard1) {
other.insert(key.clone(), value.clone(), guard2);
}
}
other
}
}
pub struct HashMapRef<'map, K, V, S, G> {
guard: MapGuard<G>,
map: &'map HashMap<K, V, S>,
}
impl<'map, K, V, S, G> HashMapRef<'map, K, V, S, G>
where
K: Hash + Eq,
S: BuildHasher,
G: Guard,
{
#[inline]
pub fn map(&self) -> &'map HashMap<K, V, S> {
self.map
}
#[inline]
pub fn len(&self) -> usize {
self.map.raw.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn contains_key<Q>(&self, key: &Q) -> bool
where
Q: Equivalent<K> + Hash + ?Sized,
{
self.get(key).is_some()
}
#[inline]
pub fn get<Q>(&self, key: &Q) -> Option<&V>
where
Q: Equivalent<K> + Hash + ?Sized,
{
match self.map.raw.get(key, &self.guard) {
Some((_, v)) => Some(v),
None => None,
}
}
#[inline]
pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
where
Q: Equivalent<K> + Hash + ?Sized,
{
self.map.raw.get(key, &self.guard)
}
#[inline]
pub fn insert(&self, key: K, value: V) -> Option<&V> {
match self.map.raw.insert(key, value, true, &self.guard) {
InsertResult::Inserted(_) => None,
InsertResult::Replaced(value) => Some(value),
InsertResult::Error { .. } => unreachable!(),
}
}
#[inline]
pub fn try_insert(&self, key: K, value: V) -> Result<&V, OccupiedError<'_, V>> {
match self.map.raw.insert(key, value, false, &self.guard) {
InsertResult::Inserted(value) => Ok(value),
InsertResult::Error {
current,
not_inserted,
} => Err(OccupiedError {
current,
not_inserted,
}),
InsertResult::Replaced(_) => unreachable!(),
}
}
#[inline]
pub fn try_insert_with<F>(&self, key: K, f: F) -> Result<&V, &V>
where
F: FnOnce() -> V,
{
self.map.raw.try_insert_with(key, f, &self.guard)
}
#[inline]
pub fn get_or_insert(&self, key: K, value: V) -> &V {
match self.try_insert(key, value) {
Ok(inserted) => inserted,
Err(OccupiedError { current, .. }) => current,
}
}
#[inline]
pub fn get_or_insert_with<F>(&self, key: K, f: F) -> &V
where
F: FnOnce() -> V,
{
self.map.raw.get_or_insert_with(key, f, &self.guard)
}
#[inline]
pub fn update<F>(&self, key: K, update: F) -> Option<&V>
where
F: Fn(&V) -> V,
{
self.map.raw.update(key, update, &self.guard)
}
#[inline]
pub fn update_or_insert<F>(&self, key: K, update: F, value: V) -> &V
where
F: Fn(&V) -> V,
{
self.update_or_insert_with(key, update, || value)
}
#[inline]
pub fn update_or_insert_with<U, F>(&self, key: K, update: U, f: F) -> &V
where
F: FnOnce() -> V,
U: Fn(&V) -> V,
{
self.map
.raw
.update_or_insert_with(key, update, f, &self.guard)
}
#[inline]
pub fn compute<'g, F, T>(&'g self, key: K, compute: F) -> Compute<'g, K, V, T>
where
F: FnMut(Option<(&'g K, &'g V)>) -> Operation<V, T>,
{
self.map.raw.compute(key, compute, &self.guard)
}
#[inline]
pub fn remove<Q>(&self, key: &Q) -> Option<&V>
where
Q: Equivalent<K> + Hash + ?Sized,
{
match self.map.raw.remove(key, &self.guard) {
Some((_, value)) => Some(value),
None => None,
}
}
#[inline]
pub fn remove_entry<Q>(&self, key: &Q) -> Option<(&K, &V)>
where
Q: Equivalent<K> + Hash + ?Sized,
{
self.map.raw.remove(key, &self.guard)
}
#[inline]
pub fn remove_if<Q, F>(&self, key: &Q, should_remove: F) -> Result<Option<(&K, &V)>, (&K, &V)>
where
Q: Equivalent<K> + Hash + ?Sized,
F: FnMut(&K, &V) -> bool,
{
self.map.raw.remove_if(key, should_remove, &self.guard)
}
#[inline]
pub fn clear(&self) {
self.map.raw.clear(&self.guard)
}
#[inline]
pub fn retain<F>(&self, f: F)
where
F: FnMut(&K, &V) -> bool,
{
self.map.raw.retain(f, &self.guard)
}
#[inline]
pub fn reserve(&self, additional: usize) {
self.map.raw.reserve(additional, &self.guard)
}
#[inline]
pub fn iter(&self) -> Iter<'_, K, V, G> {
Iter {
raw: self.map.raw.iter(&self.guard),
}
}
#[inline]
pub fn keys(&self) -> Keys<'_, K, V, G> {
Keys { iter: self.iter() }
}
#[inline]
pub fn values(&self) -> Values<'_, K, V, G> {
Values { iter: self.iter() }
}
}
impl<K, V, S, G> fmt::Debug for HashMapRef<'_, K, V, S, G>
where
K: Hash + Eq + fmt::Debug,
V: fmt::Debug,
S: BuildHasher,
G: Guard,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_map().entries(self.iter()).finish()
}
}
impl<'a, K, V, S, G> IntoIterator for &'a HashMapRef<'_, K, V, S, G>
where
K: Hash + Eq,
S: BuildHasher,
G: Guard,
{
type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V, G>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub struct Iter<'g, K, V, G> {
raw: raw::Iter<'g, K, V, MapGuard<G>>,
}
impl<'g, K: 'g, V: 'g, G> Iterator for Iter<'g, K, V, G>
where
G: Guard,
{
type Item = (&'g K, &'g V);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.raw.next()
}
}
impl<K, V, G> fmt::Debug for Iter<'_, K, V, G>
where
K: fmt::Debug,
V: fmt::Debug,
G: Guard,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list()
.entries(Iter {
raw: self.raw.clone(),
})
.finish()
}
}
pub struct Keys<'g, K, V, G> {
iter: Iter<'g, K, V, G>,
}
impl<'g, K: 'g, V: 'g, G> Iterator for Keys<'g, K, V, G>
where
G: Guard,
{
type Item = &'g K;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let (key, _) = self.iter.next()?;
Some(key)
}
}
impl<K, V, G> fmt::Debug for Keys<'_, K, V, G>
where
K: fmt::Debug,
V: fmt::Debug,
G: Guard,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Keys").field(&self.iter).finish()
}
}
pub struct Values<'g, K, V, G> {
iter: Iter<'g, K, V, G>,
}
impl<'g, K: 'g, V: 'g, G> Iterator for Values<'g, K, V, G>
where
G: Guard,
{
type Item = &'g V;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let (_, value) = self.iter.next()?;
Some(value)
}
}
impl<K, V, G> fmt::Debug for Values<'_, K, V, G>
where
K: fmt::Debug,
V: fmt::Debug,
G: Guard,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Values").field(&self.iter).finish()
}
}