use core::borrow::Borrow;
use core::hash::BuildHasher;
use core::marker::PhantomData;
use crate::growth_policy::{GrowthPolicy, LengthError, PowerOfTwo};
use crate::hasher::{EqKey, HashKey, StdEq, StdHash};
use crate::serialize::{Deserialize, DeserializeError, Deserializer, Serialize, Serializer};
use crate::sparse_hash::{
KeySelect, SparseHash, DEFAULT_INIT_BUCKET_COUNT, DEFAULT_MAX_LOAD_FACTOR,
};
use crate::sparsity::{Medium, Sparsity};
pub struct IdentityKeySelect<K>(PhantomData<K>);
impl<K> KeySelect<K> for IdentityKeySelect<K> {
type Key = K;
#[inline]
fn key(value: &K) -> &K {
value
}
}
pub struct SparseSet<K, H = StdHash, E = StdEq, P = PowerOfTwo<2>, S = Medium> {
ht: SparseHash<K, IdentityKeySelect<K>, H, E, P, S>,
}
impl<K> SparseSet<K, StdHash, StdEq, PowerOfTwo<2>, Medium> {
#[must_use]
pub fn new() -> Self {
Self::with_bucket_count(DEFAULT_INIT_BUCKET_COUNT)
}
#[must_use]
pub fn with_bucket_count(bucket_count: usize) -> Self {
Self::try_with_bucket_count(bucket_count).expect("bucket count within policy limit")
}
pub fn try_with_bucket_count(bucket_count: usize) -> Result<Self, LengthError> {
Ok(Self {
ht: SparseHash::new(
bucket_count,
StdHash::default(),
StdEq,
DEFAULT_MAX_LOAD_FACTOR,
)?,
})
}
}
impl<K, H, E, P, S> Default for SparseSet<K, H, E, P, S>
where
H: Default,
E: Default,
P: GrowthPolicy,
{
fn default() -> Self {
Self {
ht: SparseHash::new(
DEFAULT_INIT_BUCKET_COUNT,
H::default(),
E::default(),
DEFAULT_MAX_LOAD_FACTOR,
)
.expect("zero bucket count is within every policy limit"),
}
}
}
impl<K, B, P, S> SparseSet<K, StdHash<B>, StdEq, P, S>
where
K: Eq,
B: BuildHasher + Default,
P: GrowthPolicy,
S: Sparsity,
StdHash<B>: HashKey<K>,
{
#[must_use]
pub fn with_hasher_and_bucket_count(bucket_count: usize) -> Self {
Self {
ht: SparseHash::new(
bucket_count,
StdHash::default(),
StdEq,
DEFAULT_MAX_LOAD_FACTOR,
)
.expect("bucket count within policy limit"),
}
}
}
impl<K, H, E, P, S> SparseSet<K, H, E, P, S>
where
H: HashKey<K> + Clone,
E: EqKey<K, K> + Clone,
P: GrowthPolicy,
S: Sparsity,
{
#[must_use]
pub fn with_parts(bucket_count: usize, hash: H, key_eq: E) -> Self {
Self {
ht: SparseHash::new(bucket_count, hash, key_eq, DEFAULT_MAX_LOAD_FACTOR)
.expect("bucket count within policy limit"),
}
}
#[inline]
#[must_use]
pub fn len(&self) -> usize {
self.ht.len()
}
#[inline]
#[must_use]
pub fn is_empty(&self) -> bool {
self.ht.is_empty()
}
#[inline]
#[must_use]
pub fn bucket_count(&self) -> usize {
self.ht.bucket_count()
}
#[inline]
#[must_use]
pub fn max_bucket_count(&self) -> usize {
self.ht.max_bucket_count()
}
#[inline]
#[must_use]
pub fn max_size(&self) -> usize {
self.ht.max_size()
}
#[inline]
#[must_use]
pub fn load_factor(&self) -> f32 {
self.ht.load_factor()
}
#[inline]
#[must_use]
pub fn max_load_factor(&self) -> f32 {
self.ht.max_load_factor()
}
pub fn set_max_load_factor(&mut self, ml: f32) {
self.ht.set_max_load_factor(ml);
}
#[inline]
#[must_use]
pub fn hash_function(&self) -> &H {
self.ht.hash_function()
}
#[inline]
#[must_use]
pub fn key_eq(&self) -> &E {
self.ht.key_eq()
}
pub fn clear(&mut self) {
self.ht.clear();
}
pub fn rehash(&mut self, count: usize) {
self.ht.rehash(count);
}
pub fn reserve(&mut self, count: usize) {
self.ht.reserve(count);
}
pub fn insert(&mut self, key: K) -> bool {
self.ht.insert(key).1
}
#[must_use]
pub fn contains<Q>(&self, key: &Q) -> bool
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
let hash = self.ht.hash_function().hash_key(key);
self.ht.contains(key, hash)
}
#[must_use]
pub fn contains_precalc<Q>(&self, key: &Q, hash: usize) -> bool
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
self.ht.contains(key, hash)
}
#[must_use]
pub fn count<Q>(&self, key: &Q) -> usize
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
usize::from(self.contains(key))
}
#[must_use]
pub fn count_precalc<Q>(&self, key: &Q, hash: usize) -> usize
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
usize::from(self.contains_precalc(key, hash))
}
pub fn equal_range<Q>(&self, key: &Q) -> EqualRange<'_, K>
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
EqualRange {
item: self.get(key),
}
}
pub fn equal_range_precalc<Q>(&self, key: &Q, hash: usize) -> EqualRange<'_, K>
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
EqualRange {
item: self.ht.get(key, hash),
}
}
#[must_use]
pub fn get<Q>(&self, key: &Q) -> Option<&K>
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
let hash = self.ht.hash_function().hash_key(key);
self.ht.get(key, hash)
}
pub fn erase<Q>(&mut self, key: &Q) -> usize
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
let hash = self.ht.hash_function().hash_key(key);
self.ht.erase(key, hash)
}
pub fn take<Q>(&mut self, key: &Q) -> Option<K>
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
let hash = self.ht.hash_function().hash_key(key);
self.ht.remove(key, hash)
}
pub fn pop_front(&mut self) -> Option<K> {
self.ht.remove_nth(0)
}
pub fn erase_range(&mut self, skip: usize, count: usize) {
self.ht.erase_range(skip, count);
}
pub fn erase_all(&mut self) {
self.ht.erase_all();
}
pub fn retain<F>(&mut self, mut keep: F)
where
F: FnMut(&K) -> bool,
{
self.ht.retain(|k| keep(k));
}
}
impl<K, H, E, P, S> PartialEq for SparseSet<K, H, E, P, S>
where
H: HashKey<K> + Clone,
E: EqKey<K, K> + Clone,
P: GrowthPolicy,
S: Sparsity,
{
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false;
}
self.iter().all(|k| other.contains(k))
}
}
impl<K, H, E, P, S> Eq for SparseSet<K, H, E, P, S>
where
H: HashKey<K> + Clone,
E: EqKey<K, K> + Clone,
P: GrowthPolicy,
S: Sparsity,
{
}
impl<K, H, E, P, S> core::fmt::Debug for SparseSet<K, H, E, P, S>
where
K: core::fmt::Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
impl<K, H, E, P, S> Clone for SparseSet<K, H, E, P, S>
where
K: Clone,
H: Clone,
E: Clone,
P: Clone,
{
fn clone(&self) -> Self {
Self {
ht: self.ht.clone(),
}
}
}
impl<K, H, E, P, S> SparseSet<K, H, E, P, S> {
#[must_use]
pub fn iter(&self) -> Iter<'_, K> {
Iter {
inner: self.ht.iter(),
}
}
}
pub struct EqualRange<'a, K> {
item: Option<&'a K>,
}
impl<'a, K> Iterator for EqualRange<'a, K> {
type Item = &'a K;
fn next(&mut self) -> Option<&'a K> {
self.item.take()
}
}
impl<K> ExactSizeIterator for EqualRange<'_, K> {
fn len(&self) -> usize {
usize::from(self.item.is_some())
}
}
pub struct Iter<'a, K> {
inner: crate::sparse_hash::Iter<'a, K>,
}
impl<'a, K> Iterator for Iter<'a, K> {
type Item = &'a K;
fn next(&mut self) -> Option<&'a K> {
self.inner.next()
}
}
impl<'a, K, H, E, P, S> IntoIterator for &'a SparseSet<K, H, E, P, S> {
type Item = &'a K;
type IntoIter = Iter<'a, K>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub struct IntoIter<K> {
inner: crate::sparse_hash::IntoIter<K>,
}
impl<K> Iterator for IntoIter<K> {
type Item = K;
fn next(&mut self) -> Option<K> {
self.inner.next()
}
}
impl<K, H, E, P, S> IntoIterator for SparseSet<K, H, E, P, S> {
type Item = K;
type IntoIter = IntoIter<K>;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
inner: self.ht.into_values(),
}
}
}
impl<K, H, E, P, S> Extend<K> for SparseSet<K, H, E, P, S>
where
H: HashKey<K> + Clone,
E: EqKey<K, K> + Clone,
P: GrowthPolicy,
S: Sparsity,
{
fn extend<I: IntoIterator<Item = K>>(&mut self, iter: I) {
let iter = iter.into_iter();
let (lower, _) = iter.size_hint();
self.reserve(self.len() + lower);
for k in iter {
self.insert(k);
}
}
}
impl<K, H, E, P, S> SparseSet<K, H, E, P, S>
where
K: Serialize,
{
pub fn serialize<Sz: Serializer>(&self, serializer: &mut Sz) {
self.ht.serialize(serializer);
}
}
impl<K, H, E, P, S> SparseSet<K, H, E, P, S>
where
H: HashKey<K> + Clone,
E: EqKey<K, K> + Clone,
P: GrowthPolicy,
S: Sparsity,
K: Serialize + Deserialize,
{
pub fn deserialize_with<D: Deserializer>(
deserializer: &mut D,
hash_compatible: bool,
hash: H,
key_eq: E,
) -> Result<Self, DeserializeError> {
Ok(Self {
ht: SparseHash::deserialize(deserializer, hash_compatible, hash, key_eq)?,
})
}
}