use parking_lot::ReentrantMutexGuard;
use serde::{Deserializer, Serialize, Serializer};
use std::borrow::Borrow;
use std::cell::UnsafeCell;
use std::collections::{
hash_map::IntoIter as MapIntoIter, hash_map::Iter as MapIter, hash_map::IterMut as MapIterMut,
HashMap as Map, HashMap,
};
use std::fmt::{Debug, Formatter};
use std::hash::Hash;
use std::ops::{Deref, DerefMut};
use std::sync::Arc;
pub struct SyncHashMap<K: Eq + Hash, V> {
dirty: UnsafeCell<Map<K, V>>,
#[cfg(feature = "reentrant_lock")]
lock: parking_lot::ReentrantMutex<()>,
#[cfg(feature = "std_lock")]
lock: std::sync::Mutex<()>,
}
unsafe impl<K: Eq + Hash, V> Send for SyncHashMap<K, V> {}
unsafe impl<K: Eq + Hash, V> Sync for SyncHashMap<K, V> {}
impl<K, V> std::ops::Index<&K> for SyncHashMap<K, V>
where
K: Eq + Hash,
{
type Output = V;
fn index(&self, index: &K) -> &Self::Output {
unsafe { &(&*self.dirty.get())[index] }
}
}
impl<K, V> SyncHashMap<K, V>
where
K: Eq + Hash,
{
pub fn new_arc() -> Arc<Self> {
Arc::new(Self::new())
}
pub fn new() -> Self {
Self {
dirty: UnsafeCell::new(Map::new()),
lock: Default::default(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
dirty: UnsafeCell::new(Map::with_capacity(capacity)),
lock: Default::default(),
}
}
pub fn with_map(map: Map<K, V>) -> Self {
Self {
dirty: UnsafeCell::new(map),
lock: Default::default(),
}
}
pub fn insert(&self, k: K, v: V) -> Option<V> {
let _lock = self.lock.lock();
let m = unsafe { &mut *self.dirty.get() };
let r = m.insert(k, v);
r
}
pub fn insert_mut(&mut self, k: K, v: V) -> Option<V> {
let m = unsafe { &mut *self.dirty.get() };
m.insert(k, v)
}
pub fn remove(&self, k: &K) -> Option<V> {
let g = self.lock.lock();
let m = unsafe { &mut *self.dirty.get() };
let r = m.remove(k);
drop(g);
r
}
pub fn remove_mut(&mut self, k: &K) -> Option<V> {
let m = unsafe { &mut *self.dirty.get() };
m.remove(k)
}
pub fn len(&self) -> usize {
unsafe { (&*self.dirty.get()).len() }
}
pub fn is_empty(&self) -> bool {
unsafe { (&*self.dirty.get()).is_empty() }
}
pub fn clear(&self) {
let g = self.lock.lock();
let m = unsafe { &mut *self.dirty.get() };
m.clear();
drop(g);
}
pub fn clear_mut(&mut self) {
let m = unsafe { &mut *self.dirty.get() };
m.clear();
}
pub fn shrink_to_fit(&self) {
let g = self.lock.lock();
let m = unsafe { &mut *self.dirty.get() };
m.shrink_to_fit();
drop(g);
}
pub fn shrink_to_fit_mut(&mut self) {
let m = unsafe { &mut *self.dirty.get() };
m.shrink_to_fit()
}
pub fn from(map: Map<K, V>) -> Self
where
K: Eq + Hash,
{
let s = Self::with_map(map);
s
}
#[inline]
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
unsafe { (&*self.dirty.get()).get(k) }
}
#[inline]
pub fn get_mut<Q: ?Sized>(&self, k: &Q) -> Option<SyncMapRefMut<'_, V>>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
let m = unsafe { &mut *self.dirty.get() };
#[cfg(feature = "std_lock")]
let _g = match self.lock.lock() {
Ok(v) => v,
Err(_) => return None,
};
#[cfg(feature = "reentrant_lock")]
let _g = self.lock.lock();
Some(SyncMapRefMut {
_g,
value: m.get_mut(k)?,
})
}
#[inline]
pub fn contains_key(&self, x: &K) -> bool
where
K: PartialEq,
{
let m = unsafe { &mut *self.dirty.get() };
m.contains_key(x)
}
pub fn iter_mut(&self) -> IterMut<'_, K, V> {
let m = unsafe { &mut *self.dirty.get() };
#[cfg(feature = "std_lock")]
let _g = self.lock.lock().unwrap();
#[cfg(feature = "reentrant_lock")]
let _g = self.lock.lock();
return IterMut {
_g,
inner: m.iter_mut(),
};
}
pub fn iter(&self) -> MapIter<'_, K, V> {
let m = unsafe { &*self.dirty.get() };
return m.iter();
}
pub fn dirty_ref(&self) -> &HashMap<K, V> {
unsafe { &*self.dirty.get() }
}
pub fn into_inner(self) -> HashMap<K, V> {
self.dirty.into_inner()
}
}
pub struct SyncMapRefMut<'a, V> {
#[cfg(feature = "reentrant_lock")]
_g: ReentrantMutexGuard<'a, ()>,
#[cfg(feature = "std_lock")]
_g: std::sync::MutexGuard<'a, ()>,
value: &'a mut V,
}
impl<'a, V> Deref for SyncMapRefMut<'_, V> {
type Target = V;
fn deref(&self) -> &Self::Target {
self.value
}
}
impl<'a, V> DerefMut for SyncMapRefMut<'_, V> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.value
}
}
impl<'a, V> Debug for SyncMapRefMut<'_, V>
where
V: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.value.fmt(f)
}
}
impl<'a, V> PartialEq<Self> for SyncMapRefMut<'_, V>
where
V: Eq,
{
fn eq(&self, other: &Self) -> bool {
self.value.eq(&other.value)
}
}
impl<'a, V> Eq for SyncMapRefMut<'_, V> where V: Eq {}
pub struct IterMy<'a, K, V> {
inner: MapIter<'a, K, V>,
}
impl<'a, K, V> Deref for IterMy<'a, K, V> {
type Target = MapIter<'a, K, V>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<'a, K, V> Iterator for IterMy<'a, K, V> {
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
pub struct IterMut<'a, K, V> {
#[cfg(feature = "reentrant_lock")]
_g: ReentrantMutexGuard<'a, ()>,
#[cfg(feature = "std_lock")]
_g: std::sync::MutexGuard<'a, ()>,
inner: MapIterMut<'a, K, V>,
}
impl<'a, K, V> Deref for IterMut<'a, K, V> {
type Target = MapIterMut<'a, K, V>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<'a, K, V> DerefMut for IterMut<'a, K, V> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<'a, K, V> Iterator for IterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<'a, K, V> IntoIterator for &'a SyncHashMap<K, V>
where
K: Eq + Hash,
{
type Item = (&'a K, &'a V);
type IntoIter = MapIter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
unsafe { (&*self.dirty.get()).iter() }
}
}
impl<K, V> IntoIterator for SyncHashMap<K, V>
where
K: Eq + Hash,
{
type Item = (K, V);
type IntoIter = MapIntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
self.dirty.into_inner().into_iter()
}
}
impl<K: Eq + Hash, V> From<Map<K, V>> for SyncHashMap<K, V> {
fn from(arg: Map<K, V>) -> Self {
Self::from(arg)
}
}
impl<K, V> serde::Serialize for SyncHashMap<K, V>
where
K: Eq + Hash + Serialize,
V: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.dirty_ref().serialize(serializer)
}
}
impl<'de, K, V> serde::Deserialize<'de> for SyncHashMap<K, V>
where
K: Eq + Hash + serde::Deserialize<'de>,
V: serde::Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let m = Map::deserialize(deserializer)?;
Ok(Self::from(m))
}
}
impl<K, V> Debug for SyncHashMap<K, V>
where
K: Eq + Hash + Debug,
V: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.dirty_ref().fmt(f)
}
}
impl<K: Clone + Eq + Hash, V: Clone> Clone for SyncHashMap<K, V> {
fn clone(&self) -> Self {
let c = (*self.dirty_ref()).clone();
SyncHashMap::from(c)
}
}
pub mod buckets {
use super::{SyncHashMap, SyncMapRefMut};
use std::hash::{Hash, Hasher};
#[derive(Debug, Clone)]
pub struct SyncHashMapB<K: Eq + Hash, V> {
inner: Vec<SyncHashMap<K, V>>,
len: usize,
}
impl<K: Eq + Hash, V> SyncHashMapB<K, V> {
pub fn new(bucket_count: Option<usize>) -> Self {
let count = bucket_count.unwrap_or_else(|| 10);
let mut arr = vec![];
for _ in 0..count {
arr.push(SyncHashMap::new());
}
Self {
inner: arr,
len: count,
}
}
fn key_conv_to_index(&self, k: &K) -> usize {
let mut hasher = std::collections::hash_map::DefaultHasher::new();
k.hash(&mut hasher);
let hash = hasher.finish();
let index = (hash % self.len as u64) as usize;
index
}
pub fn insert(&self, k: K, v: V) -> Option<V> {
let index = self.key_conv_to_index(&k);
self.inner[index].insert(k, v)
}
pub fn insert_mut(&mut self, k: K, v: V) -> Option<V> {
let index = self.key_conv_to_index(&k);
self.inner[index].insert_mut(k, v)
}
pub fn remove(&self, k: &K) -> Option<V> {
let index = self.key_conv_to_index(&k);
self.inner[index].remove(k)
}
pub fn is_empty(&self) -> bool {
for ele in &self.inner {
if !ele.is_empty() {
return false;
}
}
true
}
pub fn len(&self) -> usize {
let mut len = 0;
for ele in &self.inner {
len += ele.len();
}
len
}
pub fn clear(&self) {
for ele in &self.inner {
ele.clear();
}
}
#[inline]
pub fn get(&self, k: &K) -> Option<&V> {
let index = self.key_conv_to_index(k);
self.inner[index].get(k)
}
pub fn get_mut(&self, k: &K) -> Option<SyncMapRefMut<'_, V>> {
let index = self.key_conv_to_index(k);
self.inner[index].get_mut(k)
}
}
}