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 PairKeySelect<K, V>(PhantomData<(K, V)>);
impl<K, V> KeySelect<(K, V)> for PairKeySelect<K, V> {
type Key = K;
#[inline]
fn key(value: &(K, V)) -> &K {
&value.0
}
}
pub struct SparseMap<K, V, H = StdHash, E = StdEq, P = PowerOfTwo<2>, S = Medium> {
ht: SparseHash<(K, V), PairKeySelect<K, V>, H, E, P, S>,
}
impl<K, V> SparseMap<K, V, 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, V, H, E, P, S> Default for SparseMap<K, V, 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, V, B, P, S> SparseMap<K, V, 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, V, H, E, P, S> SparseMap<K, V, 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"),
}
}
pub fn try_with_parts(bucket_count: usize, hash: H, key_eq: E) -> Result<Self, LengthError> {
Ok(Self {
ht: SparseHash::new(bucket_count, hash, key_eq, DEFAULT_MAX_LOAD_FACTOR)?,
})
}
#[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 max_size(&self) -> usize {
self.ht.max_size()
}
#[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 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, value: V) -> bool {
self.ht.insert((key, value)).1
}
pub fn try_insert(&mut self, key: K, value: V) -> Result<&mut V, (K, V)> {
let hash = self.ht.hash_function().hash_key(&key);
if self.ht.find_position(&key, hash).is_some() {
return Err((key, value));
}
let (pos, _inserted) = self.ht.insert_with_hash((key, value), hash);
let (_k, v) = self.ht.value_at_mut(pos);
Ok(v)
}
#[must_use]
pub fn get<Q>(&self, key: &Q) -> Option<&V>
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).map(|(_, v)| v)
}
#[must_use]
pub fn get_precalc<Q>(&self, key: &Q, hash: usize) -> Option<&V>
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
self.ht.get(key, hash).map(|(_, v)| v)
}
pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
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_mut(key, hash).map(|(_, v)| v)
}
#[must_use]
pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
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).map(|(k, v)| (k, v))
}
#[must_use]
pub fn contains_key<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_key_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(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_key_precalc(key, hash))
}
pub fn equal_range<Q>(&self, key: &Q) -> EqualRange<'_, K, V>
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
EqualRange {
item: self.get_key_value(key),
}
}
pub fn equal_range_precalc<Q>(&self, key: &Q, hash: usize) -> EqualRange<'_, K, V>
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
let item = self.ht.get(key, hash).map(|(k, v)| (k, v));
EqualRange { item }
}
#[must_use]
pub fn at<Q>(&self, key: &Q) -> &V
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
self.get(key).expect("couldn't find key")
}
#[must_use]
pub fn at_precalc<Q>(&self, key: &Q, hash: usize) -> &V
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
self.get_precalc(key, hash).expect("couldn't find key")
}
pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
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).map(|(_, v)| v)
}
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 erase_precalc<Q>(&mut self, key: &Q, hash: usize) -> usize
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<Q>,
E: EqKey<K, Q>,
{
self.ht.erase(key, hash)
}
pub fn pop_front(&mut self) -> Option<(K, V)> {
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();
}
}
impl<K, V, H, E, P, S> SparseMap<K, V, H, E, P, S>
where
H: HashKey<K> + Clone,
E: EqKey<K, K> + Clone,
P: GrowthPolicy,
S: Sparsity,
{
pub fn entry_or_default(&mut self, key: K) -> &mut V
where
V: Default,
{
self.try_emplace(key, V::default).0
}
pub fn try_emplace<F>(&mut self, key: K, make: F) -> (&mut V, bool)
where
F: FnOnce() -> V,
{
let hash = self.ht.hash_function().hash_key(&key);
if let Some(pos) = self.ht.find_position(&key, hash) {
let (_k, v) = self.ht.value_at_mut(pos);
return (v, false);
}
let value = make();
let (pos, _inserted) = self.ht.insert_with_hash((key, value), hash);
let (_k, v) = self.ht.value_at_mut(pos);
(v, true)
}
pub fn insert_or_assign(&mut self, key: K, value: V) -> (&mut V, bool) {
let hash = self.ht.hash_function().hash_key(&key);
if let Some(pos) = self.ht.find_position(&key, hash) {
let (_k, v) = self.ht.value_at_mut(pos);
*v = value;
return (v, false);
}
let (pos, _inserted) = self.ht.insert_with_hash((key, value), hash);
let (_k, v) = self.ht.value_at_mut(pos);
(v, true)
}
pub fn retain<F>(&mut self, mut keep: F)
where
F: FnMut(&K, &mut V) -> bool,
{
self.ht.retain(|(k, v)| keep(k, v));
}
}
impl<K, V, H, E, P, S> SparseMap<K, V, H, E, P, S> {
#[must_use]
pub fn iter(&self) -> Iter<'_, K, V> {
Iter {
inner: self.ht.iter(),
}
}
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
IterMut {
inner: self.ht.iter_mut(),
}
}
#[must_use]
pub fn keys(&self) -> Keys<'_, K, V> {
Keys {
inner: self.ht.iter(),
}
}
#[must_use]
pub fn values(&self) -> Values<'_, K, V> {
Values {
inner: self.ht.iter(),
}
}
}
pub struct Iter<'a, K, V> {
inner: crate::sparse_hash::Iter<'a, (K, V)>,
}
impl<'a, K, V> Iterator for Iter<'a, K, V> {
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(k, v)| (k, v))
}
}
pub struct IterMut<'a, K, V> {
inner: crate::sparse_hash::IterMut<'a, (K, V)>,
}
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().map(|(k, v)| (&*k, v))
}
}
pub struct Keys<'a, K, V> {
inner: crate::sparse_hash::Iter<'a, (K, V)>,
}
impl<'a, K, V> Iterator for Keys<'a, K, V> {
type Item = &'a K;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(k, _)| k)
}
}
pub struct EqualRange<'a, K, V> {
item: Option<(&'a K, &'a V)>,
}
impl<'a, K, V> Iterator for EqualRange<'a, K, V> {
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.item.take()
}
}
impl<K, V> ExactSizeIterator for EqualRange<'_, K, V> {
fn len(&self) -> usize {
usize::from(self.item.is_some())
}
}
pub struct Values<'a, K, V> {
inner: crate::sparse_hash::Iter<'a, (K, V)>,
}
impl<'a, K, V> Iterator for Values<'a, K, V> {
type Item = &'a V;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(_, v)| v)
}
}
impl<'a, K, V, H, E, P, S> IntoIterator for &'a SparseMap<K, V, H, E, P, S> {
type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, K, V, H, E, P, S> IntoIterator for &'a mut SparseMap<K, V, H, E, P, S> {
type Item = (&'a K, &'a mut V);
type IntoIter = IterMut<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
pub struct IntoIter<K, V> {
inner: crate::sparse_hash::IntoIter<(K, V)>,
}
impl<K, V> Iterator for IntoIter<K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<(K, V)> {
self.inner.next()
}
}
impl<K, V, H, E, P, S> IntoIterator for SparseMap<K, V, H, E, P, S> {
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
inner: self.ht.into_values(),
}
}
}
impl<K, V, H, E, P, S> Extend<(K, V)> for SparseMap<K, V, H, E, P, S>
where
H: HashKey<K> + Clone,
E: EqKey<K, K> + Clone,
P: GrowthPolicy,
S: Sparsity,
{
fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
let iter = iter.into_iter();
let (lower, _) = iter.size_hint();
self.reserve(self.len() + lower);
for (k, v) in iter {
self.insert(k, v);
}
}
}
impl<K, V, H, E, P, S> PartialEq for SparseMap<K, V, H, E, P, S>
where
V: PartialEq,
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;
}
for (k, v) in self.iter() {
match other.get(k) {
Some(ov) if ov == v => {}
_ => return false,
}
}
true
}
}
impl<K, V, H, E, P, S> Eq for SparseMap<K, V, H, E, P, S>
where
V: Eq,
H: HashKey<K> + Clone,
E: EqKey<K, K> + Clone,
P: GrowthPolicy,
S: Sparsity,
{
}
impl<K, V, H, E, P, S> core::fmt::Debug for SparseMap<K, V, H, E, P, S>
where
K: core::fmt::Debug,
V: core::fmt::Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_map().entries(self.iter()).finish()
}
}
impl<K, V, H, E, P, S, Q> core::ops::Index<&Q> for SparseMap<K, V, H, E, P, S>
where
K: Borrow<Q>,
Q: ?Sized,
H: HashKey<K> + HashKey<Q> + Clone,
E: EqKey<K, K> + EqKey<K, Q> + Clone,
P: GrowthPolicy,
S: Sparsity,
{
type Output = V;
fn index(&self, key: &Q) -> &V {
self.at(key)
}
}
impl<K, V, H, E, P, S> Clone for SparseMap<K, V, H, E, P, S>
where
(K, V): Clone,
H: Clone,
E: Clone,
P: Clone,
{
fn clone(&self) -> Self {
Self {
ht: self.ht.clone(),
}
}
}
impl<K, V, H, E, P, S> SparseMap<K, V, H, E, P, S>
where
(K, V): Serialize,
{
pub fn serialize<Sz: Serializer>(&self, serializer: &mut Sz) {
self.ht.serialize(serializer);
}
}
impl<K, V, H, E, P, S> SparseMap<K, V, H, E, P, S>
where
H: HashKey<K> + Clone,
E: EqKey<K, K> + Clone,
P: GrowthPolicy,
S: Sparsity,
(K, V): 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)?,
})
}
}