use crate::raw::utils::MapGuard;
use crate::raw::{self, InsertResult};
use crate::Equivalent;
use seize::{Collector, Guard, LocalGuard, OwnedGuard};
use crate::map::ResizeMode;
use std::collections::hash_map::RandomState;
use std::fmt;
use std::hash::{BuildHasher, Hash};
use std::marker::PhantomData;
pub struct HashSet<K, S = RandomState> {
raw: raw::HashMap<K, (), S>,
}
unsafe impl<K: Send, S: Send> Send for HashSet<K, S> {}
unsafe impl<K: Sync, S: Sync> Sync for HashSet<K, S> {}
pub struct HashSetBuilder<K, S = RandomState> {
hasher: S,
capacity: usize,
collector: Collector,
resize_mode: ResizeMode,
_kv: PhantomData<K>,
}
impl<K> HashSetBuilder<K> {
pub fn hasher<S>(self, hasher: S) -> HashSetBuilder<K, S> {
HashSetBuilder {
hasher,
capacity: self.capacity,
collector: self.collector,
resize_mode: self.resize_mode,
_kv: PhantomData,
}
}
}
impl<K, S> HashSetBuilder<K, S> {
pub fn capacity(self, capacity: usize) -> HashSetBuilder<K, S> {
HashSetBuilder {
capacity,
hasher: self.hasher,
collector: self.collector,
resize_mode: self.resize_mode,
_kv: PhantomData,
}
}
pub fn resize_mode(self, resize_mode: ResizeMode) -> Self {
HashSetBuilder {
resize_mode,
hasher: self.hasher,
capacity: self.capacity,
collector: self.collector,
_kv: PhantomData,
}
}
pub fn collector(self, collector: Collector) -> Self {
HashSetBuilder {
collector,
hasher: self.hasher,
capacity: self.capacity,
resize_mode: self.resize_mode,
_kv: PhantomData,
}
}
pub fn build(self) -> HashSet<K, S> {
HashSet {
raw: raw::HashMap::new(self.capacity, self.hasher, self.collector, self.resize_mode),
}
}
}
impl<K, S> fmt::Debug for HashSetBuilder<K, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("HashSetBuilder")
.field("capacity", &self.capacity)
.field("collector", &self.collector)
.field("resize_mode", &self.resize_mode)
.finish()
}
}
impl<K> HashSet<K> {
pub fn new() -> HashSet<K> {
HashSet::with_capacity_and_hasher(0, RandomState::new())
}
pub fn with_capacity(capacity: usize) -> HashSet<K> {
HashSet::with_capacity_and_hasher(capacity, RandomState::new())
}
pub fn builder() -> HashSetBuilder<K> {
HashSetBuilder {
capacity: 0,
hasher: RandomState::default(),
collector: Collector::new(),
resize_mode: ResizeMode::default(),
_kv: PhantomData,
}
}
}
impl<K, S> Default for HashSet<K, S>
where
S: Default,
{
fn default() -> Self {
HashSet::with_hasher(S::default())
}
}
impl<K, S> HashSet<K, S> {
pub fn with_hasher(hash_builder: S) -> HashSet<K, S> {
HashSet::with_capacity_and_hasher(0, hash_builder)
}
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashSet<K, S> {
HashSet {
raw: raw::HashMap::new(
capacity,
hash_builder,
Collector::default(),
ResizeMode::default(),
),
}
}
#[inline]
pub fn pin(&self) -> HashSetRef<'_, K, S, LocalGuard<'_>> {
HashSetRef {
guard: self.raw.guard(),
set: self,
}
}
#[inline]
pub fn pin_owned(&self) -> HashSetRef<'_, K, S, OwnedGuard<'_>> {
HashSetRef {
guard: self.raw.owned_guard(),
set: 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, S> HashSet<K, 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<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 K>
where
Q: Equivalent<K> + Hash + ?Sized,
{
match self.raw.get(key, self.raw.verify(guard)) {
Some((key, _)) => Some(key),
None => None,
}
}
#[inline]
pub fn insert(&self, key: K, guard: &impl Guard) -> bool {
match self.raw.insert(key, (), true, self.raw.verify(guard)) {
InsertResult::Inserted(_) => true,
InsertResult::Replaced(_) => false,
InsertResult::Error { .. } => unreachable!(),
}
}
#[inline]
pub fn remove<Q>(&self, key: &Q, guard: &impl Guard) -> bool
where
Q: Equivalent<K> + Hash + ?Sized,
{
match self.raw.remove(key, self.raw.verify(guard)) {
Some((_, _)) => true,
None => false,
}
}
#[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>(&mut self, mut f: F, guard: &impl Guard)
where
F: FnMut(&K) -> bool,
{
self.raw.retain(|k, _| f(k), self.raw.verify(guard))
}
#[inline]
pub fn iter<'g, G>(&self, guard: &'g G) -> Iter<'g, K, G>
where
G: Guard,
{
Iter {
raw: self.raw.iter(self.raw.verify(guard)),
}
}
}
impl<K, S> PartialEq for HashSet<K, S>
where
K: Hash + Eq,
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| other.get(key, guard2).is_some())
}
}
impl<K, S> Eq for HashSet<K, S>
where
K: Hash + Eq,
S: BuildHasher,
{
}
impl<K, S> fmt::Debug for HashSet<K, S>
where
K: Hash + Eq + fmt::Debug,
S: BuildHasher,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let guard = self.guard();
f.debug_set().entries(self.iter(&guard)).finish()
}
}
impl<K, S> Extend<K> for &HashSet<K, S>
where
K: Hash + Eq,
S: BuildHasher,
{
fn extend<T: IntoIterator<Item = K>>(&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 in iter {
self.insert(key, &guard);
}
}
}
impl<'a, K, S> Extend<&'a K> for &HashSet<K, S>
where
K: Copy + Hash + Eq + 'a,
S: BuildHasher,
{
fn extend<T: IntoIterator<Item = &'a K>>(&mut self, iter: T) {
self.extend(iter.into_iter().copied());
}
}
impl<K, const N: usize> From<[K; N]> for HashSet<K, RandomState>
where
K: Hash + Eq,
{
fn from(arr: [K; N]) -> Self {
HashSet::from_iter(arr)
}
}
impl<K, S> FromIterator<K> for HashSet<K, S>
where
K: Hash + Eq,
S: BuildHasher + Default,
{
fn from_iter<T: IntoIterator<Item = K>>(iter: T) -> Self {
let mut iter = iter.into_iter();
if let Some(key) = iter.next() {
let (lower, _) = iter.size_hint();
let set = HashSet::with_capacity_and_hasher(lower.saturating_add(1), S::default());
{
let set = set.pin();
set.insert(key);
for key in iter {
set.insert(key);
}
}
set
} else {
Self::default()
}
}
}
impl<K, S> Clone for HashSet<K, S>
where
K: Clone + Hash + Eq,
S: BuildHasher + Clone,
{
fn clone(&self) -> HashSet<K, S> {
let other = HashSet::builder()
.capacity(self.len())
.hasher(self.raw.hasher.clone())
.collector(seize::Collector::new())
.build();
{
let (guard1, guard2) = (&self.guard(), &other.guard());
for key in self.iter(guard1) {
other.insert(key.clone(), guard2);
}
}
other
}
}
pub struct HashSetRef<'set, K, S, G> {
guard: MapGuard<G>,
set: &'set HashSet<K, S>,
}
impl<'set, K, S, G> HashSetRef<'set, K, S, G>
where
K: Hash + Eq,
S: BuildHasher,
G: Guard,
{
#[inline]
pub fn set(&self) -> &'set HashSet<K, S> {
self.set
}
#[inline]
pub fn len(&self) -> usize {
self.set.raw.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn contains<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<&K>
where
Q: Equivalent<K> + Hash + ?Sized,
{
match self.set.raw.get(key, &self.guard) {
Some((k, _)) => Some(k),
None => None,
}
}
#[inline]
pub fn insert(&self, key: K) -> bool {
match self.set.raw.insert(key, (), true, &self.guard) {
InsertResult::Inserted(_) => true,
InsertResult::Replaced(_) => false,
InsertResult::Error { .. } => unreachable!(),
}
}
#[inline]
pub fn remove<Q>(&self, key: &Q) -> bool
where
Q: Equivalent<K> + Hash + ?Sized,
{
match self.set.raw.remove(key, &self.guard) {
Some((_, _)) => true,
None => false,
}
}
#[inline]
pub fn clear(&self) {
self.set.raw.clear(&self.guard)
}
#[inline]
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&K) -> bool,
{
self.set.raw.retain(|k, _| f(k), &self.guard)
}
#[inline]
pub fn reserve(&self, additional: usize) {
self.set.raw.reserve(additional, &self.guard)
}
#[inline]
pub fn iter(&self) -> Iter<'_, K, G> {
Iter {
raw: self.set.raw.iter(&self.guard),
}
}
}
impl<K, S, G> fmt::Debug for HashSetRef<'_, K, S, G>
where
K: Hash + Eq + fmt::Debug,
S: BuildHasher,
G: Guard,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
impl<'a, K, S, G> IntoIterator for &'a HashSetRef<'_, K, S, G>
where
K: Hash + Eq,
S: BuildHasher,
G: Guard,
{
type Item = &'a K;
type IntoIter = Iter<'a, K, G>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub struct Iter<'g, K, G> {
raw: raw::Iter<'g, K, (), MapGuard<G>>,
}
impl<'g, K: 'g, G> Iterator for Iter<'g, K, G>
where
G: Guard,
{
type Item = &'g K;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.raw.next().map(|(k, _)| k)
}
}
impl<K, G> fmt::Debug for Iter<'_, K, G>
where
K: fmt::Debug,
G: Guard,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list()
.entries(Iter {
raw: self.raw.clone(),
})
.finish()
}
}