126 lines
2.6 KiB
Rust
126 lines
2.6 KiB
Rust
use {
|
|
crate::{
|
|
clonecell::UnsafeCellCloneSafe,
|
|
ptr_ext::{MutPtrExt, PtrExt},
|
|
},
|
|
ahash::AHashMap,
|
|
std::{
|
|
borrow::Borrow,
|
|
cell::UnsafeCell,
|
|
fmt::{Debug, Formatter},
|
|
hash::Hash,
|
|
mem,
|
|
ops::{Deref, DerefMut},
|
|
},
|
|
};
|
|
|
|
pub struct CopyHashMap<K, V> {
|
|
map: UnsafeCell<AHashMap<K, V>>,
|
|
}
|
|
|
|
impl<K: Debug, V: Debug> Debug for CopyHashMap<K, V> {
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
self.map.fmt(f)
|
|
}
|
|
}
|
|
|
|
impl<K, V> Default for CopyHashMap<K, V> {
|
|
fn default() -> Self {
|
|
Self {
|
|
map: Default::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<K: Eq + Hash, V> CopyHashMap<K, V> {
|
|
pub fn new() -> Self {
|
|
Self::default()
|
|
}
|
|
|
|
pub fn set(&self, k: K, v: V) -> Option<V> {
|
|
unsafe { self.map.get().deref_mut().insert(k, v) }
|
|
}
|
|
|
|
pub fn get<Q>(&self, k: &Q) -> Option<V>
|
|
where
|
|
V: UnsafeCellCloneSafe,
|
|
Q: Hash + Eq + ?Sized,
|
|
K: Borrow<Q>,
|
|
{
|
|
unsafe { self.map.get().deref().get(k).cloned() }
|
|
}
|
|
|
|
pub fn remove<Q>(&self, k: &Q) -> Option<V>
|
|
where
|
|
Q: Hash + Eq + ?Sized,
|
|
K: Borrow<Q>,
|
|
{
|
|
unsafe { self.map.get().deref_mut().remove(k) }
|
|
}
|
|
|
|
pub fn contains<Q>(&self, k: &Q) -> bool
|
|
where
|
|
Q: Hash + Eq + ?Sized,
|
|
K: Borrow<Q>,
|
|
{
|
|
unsafe { self.map.get().deref().contains_key(k) }
|
|
}
|
|
|
|
pub fn not_contains<Q>(&self, k: &Q) -> bool
|
|
where
|
|
Q: Hash + Eq + ?Sized,
|
|
K: Borrow<Q>,
|
|
{
|
|
!self.contains(k)
|
|
}
|
|
|
|
pub fn lock(&self) -> Locked<'_, K, V> {
|
|
Locked {
|
|
source: self,
|
|
map: self.clear(),
|
|
}
|
|
}
|
|
|
|
pub fn clear(&self) -> AHashMap<K, V> {
|
|
unsafe { mem::take(self.map.get().deref_mut()) }
|
|
}
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
unsafe { self.map.get().deref().is_empty() }
|
|
}
|
|
|
|
pub fn is_not_empty(&self) -> bool {
|
|
!self.is_empty()
|
|
}
|
|
|
|
pub fn len(&self) -> usize {
|
|
unsafe { self.map.get().deref().len() }
|
|
}
|
|
}
|
|
|
|
pub struct Locked<'a, K, V> {
|
|
source: &'a CopyHashMap<K, V>,
|
|
map: AHashMap<K, V>,
|
|
}
|
|
|
|
impl<'a, K, V> Drop for Locked<'a, K, V> {
|
|
fn drop(&mut self) {
|
|
unsafe {
|
|
mem::swap(&mut self.map, self.source.map.get().deref_mut());
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a, K, V> Deref for Locked<'a, K, V> {
|
|
type Target = AHashMap<K, V>;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.map
|
|
}
|
|
}
|
|
|
|
impl<'a, K, V> DerefMut for Locked<'a, K, V> {
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
&mut self.map
|
|
}
|
|
}
|