use super::ebr::Barrier;
use super::HashMap;
use std::borrow::Borrow;
use std::collections::hash_map::RandomState;
use std::hash::{BuildHasher, Hash};
pub struct HashSet<K, H = RandomState>
where
K: 'static + Eq + Hash + Sync,
H: BuildHasher,
{
map: HashMap<K, (), H>,
}
impl<K, H> HashSet<K, H>
where
K: 'static + Eq + Hash + Sync,
H: BuildHasher,
{
pub fn new(capacity: usize, build_hasher: H) -> HashSet<K, H> {
HashSet {
map: HashMap::new(capacity, build_hasher),
}
}
pub fn reserve(&self, capacity: usize) -> Option<Ticket<K, H>> {
self.map.reserve(capacity)
}
#[inline]
pub fn insert(&self, key: K) -> Result<(), K> {
if let Err((k, _)) = self.map.insert(key, ()) {
return Err(k);
}
Ok(())
}
#[inline]
pub fn remove<Q>(&self, key_ref: &Q) -> Option<K>
where
K: Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
self.map.remove(key_ref).map(|(k, _)| k)
}
#[inline]
pub fn remove_if<Q, F: FnOnce() -> bool>(&self, key_ref: &Q, condition: F) -> Option<K>
where
K: Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
self.map.remove_if(key_ref, |_| condition()).map(|(k, _)| k)
}
#[inline]
pub fn read<Q, R, F: FnOnce(&K) -> R>(&self, key_ref: &Q, reader: F) -> Option<R>
where
K: Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
let barrier = Barrier::new();
self.read_with(key_ref, reader, &barrier)
}
#[inline]
pub fn read_with<'b, Q, R, F: FnOnce(&'b K) -> R>(
&self,
key_ref: &Q,
reader: F,
barrier: &'b Barrier,
) -> Option<R>
where
K: Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
self.map.read_with(key_ref, |k, _| reader(k), barrier)
}
#[inline]
pub fn contains<Q>(&self, key: &Q) -> bool
where
K: Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
self.read(key, |_| ()).is_some()
}
#[inline]
pub fn for_each<F: FnMut(&K)>(&self, mut f: F) {
self.map.retain(|k, _| {
f(k);
true
});
}
pub fn retain<F: FnMut(&K) -> bool>(&self, mut filter: F) -> (usize, usize) {
self.map.retain(|k, _| filter(k))
}
#[inline]
pub fn clear(&self) -> usize {
self.map.clear()
}
#[inline]
pub fn len(&self) -> usize {
self.map.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
#[inline]
pub fn capacity(&self) -> usize {
self.map.capacity()
}
}
impl<K: 'static + Eq + Hash + Sync> Default for HashSet<K, RandomState> {
fn default() -> Self {
HashSet {
map: HashMap::default(),
}
}
}
pub type Ticket<'h, K, H> = super::hash_map::Ticket<'h, K, (), H>;