Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parametrize RawTable, HashSet and HashMap over an allocator #133

Merged
merged 16 commits into from
Oct 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 86 additions & 51 deletions src/external_trait_impls/rayon/map.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Rayon extensions for `HashMap`.

use crate::hash_map::HashMap;
use crate::raw::{AllocRef, Global};
use core::fmt;
use core::hash::{BuildHasher, Hash};
use rayon::iter::plumbing::UnindexedConsumer;
Expand All @@ -15,11 +16,13 @@ use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelExtend, Pa
/// [`par_iter`]: /hashbrown/struct.HashMap.html#method.par_iter
/// [`HashMap`]: /hashbrown/struct.HashMap.html
/// [`IntoParallelRefIterator`]: https://docs.rs/rayon/1.0/rayon/iter/trait.IntoParallelRefIterator.html
pub struct ParIter<'a, K, V, S> {
map: &'a HashMap<K, V, S>,
pub struct ParIter<'a, K, V, S, A: AllocRef + Clone = Global> {
map: &'a HashMap<K, V, S, A>,
}

impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParIter<'a, K, V, S> {
impl<'a, K: Sync, V: Sync, S: Sync, A: AllocRef + Clone + Sync> ParallelIterator
for ParIter<'a, K, V, S, A>
{
type Item = (&'a K, &'a V);

#[cfg_attr(feature = "inline-more", inline)]
Expand All @@ -36,14 +39,16 @@ impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParIter<'a, K, V, S> {
}
}

impl<K, V, S> Clone for ParIter<'_, K, V, S> {
impl<K, V, S, A: AllocRef + Clone> Clone for ParIter<'_, K, V, S, A> {
#[cfg_attr(feature = "inline-more", inline)]
fn clone(&self) -> Self {
ParIter { map: self.map }
}
}

impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, S: BuildHasher> fmt::Debug for ParIter<'_, K, V, S> {
impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, S: BuildHasher, A: AllocRef + Clone> fmt::Debug
for ParIter<'_, K, V, S, A>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.map.iter().fmt(f)
}
Expand All @@ -56,11 +61,13 @@ impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, S: BuildHasher> fmt::Debug for Pa
///
/// [`par_keys`]: /hashbrown/struct.HashMap.html#method.par_keys
/// [`HashMap`]: /hashbrown/struct.HashMap.html
pub struct ParKeys<'a, K, V, S> {
map: &'a HashMap<K, V, S>,
pub struct ParKeys<'a, K, V, S, A: AllocRef + Clone> {
map: &'a HashMap<K, V, S, A>,
}

impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParKeys<'a, K, V, S> {
impl<'a, K: Sync, V: Sync, S: Sync, A: AllocRef + Clone + Sync> ParallelIterator
for ParKeys<'a, K, V, S, A>
{
type Item = &'a K;

#[cfg_attr(feature = "inline-more", inline)]
Expand All @@ -74,14 +81,16 @@ impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParKeys<'a, K, V, S> {
}
}

impl<K, V, S> Clone for ParKeys<'_, K, V, S> {
impl<K, V, S, A: AllocRef + Clone> Clone for ParKeys<'_, K, V, S, A> {
#[cfg_attr(feature = "inline-more", inline)]
fn clone(&self) -> Self {
ParKeys { map: self.map }
}
}

impl<K: fmt::Debug + Eq + Hash, V, S: BuildHasher> fmt::Debug for ParKeys<'_, K, V, S> {
impl<K: fmt::Debug + Eq + Hash, V, S: BuildHasher, A: AllocRef + Clone> fmt::Debug
for ParKeys<'_, K, V, S, A>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.map.keys().fmt(f)
}
Expand All @@ -94,11 +103,13 @@ impl<K: fmt::Debug + Eq + Hash, V, S: BuildHasher> fmt::Debug for ParKeys<'_, K,
///
/// [`par_values`]: /hashbrown/struct.HashMap.html#method.par_values
/// [`HashMap`]: /hashbrown/struct.HashMap.html
pub struct ParValues<'a, K, V, S> {
map: &'a HashMap<K, V, S>,
pub struct ParValues<'a, K, V, S, A: AllocRef + Clone = Global> {
map: &'a HashMap<K, V, S, A>,
}

impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParValues<'a, K, V, S> {
impl<'a, K: Sync, V: Sync, S: Sync, A: AllocRef + Clone + Sync> ParallelIterator
for ParValues<'a, K, V, S, A>
{
type Item = &'a V;

#[cfg_attr(feature = "inline-more", inline)]
Expand All @@ -112,14 +123,16 @@ impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParValues<'a, K, V, S>
}
}

impl<K, V, S> Clone for ParValues<'_, K, V, S> {
impl<K, V, S, A: AllocRef + Clone> Clone for ParValues<'_, K, V, S, A> {
#[cfg_attr(feature = "inline-more", inline)]
fn clone(&self) -> Self {
ParValues { map: self.map }
}
}

impl<K: Eq + Hash, V: fmt::Debug, S: BuildHasher> fmt::Debug for ParValues<'_, K, V, S> {
impl<K: Eq + Hash, V: fmt::Debug, S: BuildHasher, A: AllocRef + Clone> fmt::Debug
for ParValues<'_, K, V, S, A>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.map.values().fmt(f)
}
Expand All @@ -134,11 +147,13 @@ impl<K: Eq + Hash, V: fmt::Debug, S: BuildHasher> fmt::Debug for ParValues<'_, K
/// [`par_iter_mut`]: /hashbrown/struct.HashMap.html#method.par_iter_mut
/// [`HashMap`]: /hashbrown/struct.HashMap.html
/// [`IntoParallelRefMutIterator`]: https://docs.rs/rayon/1.0/rayon/iter/trait.IntoParallelRefMutIterator.html
pub struct ParIterMut<'a, K, V, S> {
map: &'a mut HashMap<K, V, S>,
pub struct ParIterMut<'a, K, V, S, A: AllocRef + Clone> {
map: &'a mut HashMap<K, V, S, A>,
}

impl<'a, K: Send + Sync, V: Send, S: Send> ParallelIterator for ParIterMut<'a, K, V, S> {
impl<'a, K: Send + Sync, V: Send, S: Send, A: AllocRef + Clone + Sync> ParallelIterator
for ParIterMut<'a, K, V, S, A>
{
type Item = (&'a K, &'a mut V);

#[cfg_attr(feature = "inline-more", inline)]
Expand All @@ -155,8 +170,8 @@ impl<'a, K: Send + Sync, V: Send, S: Send> ParallelIterator for ParIterMut<'a, K
}
}

impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, S: BuildHasher> fmt::Debug
for ParIterMut<'_, K, V, S>
impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, S: BuildHasher, A: AllocRef + Clone> fmt::Debug
for ParIterMut<'_, K, V, S, A>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.map.iter().fmt(f)
Expand All @@ -170,11 +185,13 @@ impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, S: BuildHasher> fmt::Debug
///
/// [`par_values_mut`]: /hashbrown/struct.HashMap.html#method.par_values_mut
/// [`HashMap`]: /hashbrown/struct.HashMap.html
pub struct ParValuesMut<'a, K, V, S> {
map: &'a mut HashMap<K, V, S>,
pub struct ParValuesMut<'a, K, V, S, A: AllocRef + Clone = Global> {
map: &'a mut HashMap<K, V, S, A>,
}

impl<'a, K: Send, V: Send, S: Send> ParallelIterator for ParValuesMut<'a, K, V, S> {
impl<'a, K: Send, V: Send, S: Send, A: AllocRef + Clone + Send> ParallelIterator
for ParValuesMut<'a, K, V, S, A>
{
type Item = &'a mut V;

#[cfg_attr(feature = "inline-more", inline)]
Expand All @@ -188,7 +205,9 @@ impl<'a, K: Send, V: Send, S: Send> ParallelIterator for ParValuesMut<'a, K, V,
}
}

impl<K: Eq + Hash, V: fmt::Debug, S: BuildHasher> fmt::Debug for ParValuesMut<'_, K, V, S> {
impl<K: Eq + Hash, V: fmt::Debug, S: BuildHasher, A: AllocRef + Clone> fmt::Debug
for ParValuesMut<'_, K, V, S, A>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.map.values().fmt(f)
}
Expand All @@ -203,11 +222,13 @@ impl<K: Eq + Hash, V: fmt::Debug, S: BuildHasher> fmt::Debug for ParValuesMut<'_
/// [`into_par_iter`]: /hashbrown/struct.HashMap.html#method.into_par_iter
/// [`HashMap`]: /hashbrown/struct.HashMap.html
/// [`IntoParallelIterator`]: https://docs.rs/rayon/1.0/rayon/iter/trait.IntoParallelIterator.html
pub struct IntoParIter<K, V, S> {
map: HashMap<K, V, S>,
pub struct IntoParIter<K, V, S, A: AllocRef + Clone = Global> {
map: HashMap<K, V, S, A>,
}

impl<K: Send, V: Send, S: Send> ParallelIterator for IntoParIter<K, V, S> {
impl<K: Send, V: Send, S: Send, A: AllocRef + Clone + Send> ParallelIterator
for IntoParIter<K, V, S, A>
{
type Item = (K, V);

#[cfg_attr(feature = "inline-more", inline)]
Expand All @@ -219,7 +240,9 @@ impl<K: Send, V: Send, S: Send> ParallelIterator for IntoParIter<K, V, S> {
}
}

impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, S: BuildHasher> fmt::Debug for IntoParIter<K, V, S> {
impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, S: BuildHasher, A: AllocRef + Clone> fmt::Debug
for IntoParIter<K, V, S, A>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.map.iter().fmt(f)
}
Expand All @@ -232,11 +255,13 @@ impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, S: BuildHasher> fmt::Debug for In
///
/// [`par_drain`]: /hashbrown/struct.HashMap.html#method.par_drain
/// [`HashMap`]: /hashbrown/struct.HashMap.html
pub struct ParDrain<'a, K, V, S> {
map: &'a mut HashMap<K, V, S>,
pub struct ParDrain<'a, K, V, S, A: AllocRef + Clone = Global> {
map: &'a mut HashMap<K, V, S, A>,
}

impl<K: Send, V: Send, S: Send> ParallelIterator for ParDrain<'_, K, V, S> {
impl<K: Send, V: Send, S: Send, A: AllocRef + Clone + Sync> ParallelIterator
for ParDrain<'_, K, V, S, A>
{
type Item = (K, V);

#[cfg_attr(feature = "inline-more", inline)]
Expand All @@ -248,48 +273,49 @@ impl<K: Send, V: Send, S: Send> ParallelIterator for ParDrain<'_, K, V, S> {
}
}

impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, S: BuildHasher> fmt::Debug
for ParDrain<'_, K, V, S>
impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, S: BuildHasher, A: AllocRef + Clone> fmt::Debug
for ParDrain<'_, K, V, S, A>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.map.iter().fmt(f)
}
}

impl<K: Sync, V: Sync, S: Sync> HashMap<K, V, S> {
impl<K: Sync, V: Sync, S: Sync, A: AllocRef + Clone + Sync> HashMap<K, V, S, A> {
/// Visits (potentially in parallel) immutably borrowed keys in an arbitrary order.
#[cfg_attr(feature = "inline-more", inline)]
pub fn par_keys(&self) -> ParKeys<'_, K, V, S> {
pub fn par_keys(&self) -> ParKeys<'_, K, V, S, A> {
ParKeys { map: self }
}

/// Visits (potentially in parallel) immutably borrowed values in an arbitrary order.
#[cfg_attr(feature = "inline-more", inline)]
pub fn par_values(&self) -> ParValues<'_, K, V, S> {
pub fn par_values(&self) -> ParValues<'_, K, V, S, A> {
ParValues { map: self }
}
}

impl<K: Send, V: Send, S: Send> HashMap<K, V, S> {
impl<K: Send, V: Send, S: Send, A: AllocRef + Clone + Sync> HashMap<K, V, S, A> {
/// Visits (potentially in parallel) mutably borrowed values in an arbitrary order.
#[cfg_attr(feature = "inline-more", inline)]
pub fn par_values_mut(&mut self) -> ParValuesMut<'_, K, V, S> {
pub fn par_values_mut(&mut self) -> ParValuesMut<'_, K, V, S, A> {
ParValuesMut { map: self }
}

/// Consumes (potentially in parallel) all values in an arbitrary order,
/// while preserving the map's allocated memory for reuse.
#[cfg_attr(feature = "inline-more", inline)]
pub fn par_drain(&mut self) -> ParDrain<'_, K, V, S> {
pub fn par_drain(&mut self) -> ParDrain<'_, K, V, S, A> {
ParDrain { map: self }
}
}

impl<K, V, S> HashMap<K, V, S>
impl<K, V, S, A> HashMap<K, V, S, A>
where
K: Eq + Hash + Sync,
V: PartialEq + Sync,
S: BuildHasher + Sync,
A: AllocRef + Clone + Sync,
{
/// Returns `true` if the map is equal to another,
/// i.e. both maps contain the same keys mapped to the same values.
Expand All @@ -303,29 +329,35 @@ where
}
}

impl<K: Send, V: Send, S: Send> IntoParallelIterator for HashMap<K, V, S> {
impl<K: Send, V: Send, S: Send, A: AllocRef + Clone + Send> IntoParallelIterator
for HashMap<K, V, S, A>
{
type Item = (K, V);
type Iter = IntoParIter<K, V, S>;
type Iter = IntoParIter<K, V, S, A>;

#[cfg_attr(feature = "inline-more", inline)]
fn into_par_iter(self) -> Self::Iter {
IntoParIter { map: self }
}
}

impl<'a, K: Sync, V: Sync, S: Sync> IntoParallelIterator for &'a HashMap<K, V, S> {
impl<'a, K: Sync, V: Sync, S: Sync, A: AllocRef + Clone + Sync> IntoParallelIterator
for &'a HashMap<K, V, S, A>
{
type Item = (&'a K, &'a V);
type Iter = ParIter<'a, K, V, S>;
type Iter = ParIter<'a, K, V, S, A>;

#[cfg_attr(feature = "inline-more", inline)]
fn into_par_iter(self) -> Self::Iter {
ParIter { map: self }
}
}

impl<'a, K: Send + Sync, V: Send, S: Send> IntoParallelIterator for &'a mut HashMap<K, V, S> {
impl<'a, K: Send + Sync, V: Send, S: Send, A: AllocRef + Clone + Sync> IntoParallelIterator
for &'a mut HashMap<K, V, S, A>
{
type Item = (&'a K, &'a mut V);
type Iter = ParIterMut<'a, K, V, S>;
type Iter = ParIterMut<'a, K, V, S, A>;

#[cfg_attr(feature = "inline-more", inline)]
fn into_par_iter(self) -> Self::Iter {
Expand All @@ -337,7 +369,7 @@ impl<'a, K: Send + Sync, V: Send, S: Send> IntoParallelIterator for &'a mut Hash
/// hashmap. If multiple pairs correspond to the same key, then the
/// ones produced earlier in the parallel iterator will be
/// overwritten, just as with a sequential iterator.
impl<K, V, S> FromParallelIterator<(K, V)> for HashMap<K, V, S>
impl<K, V, S> FromParallelIterator<(K, V)> for HashMap<K, V, S, Global>
where
K: Eq + Hash + Send,
V: Send,
Expand All @@ -354,11 +386,12 @@ where
}

/// Extend a hash map with items from a parallel iterator.
impl<K, V, S> ParallelExtend<(K, V)> for HashMap<K, V, S>
impl<K, V, S, A> ParallelExtend<(K, V)> for HashMap<K, V, S, A>
where
K: Eq + Hash + Send,
V: Send,
S: BuildHasher,
A: AllocRef + Clone,
{
fn par_extend<I>(&mut self, par_iter: I)
where
Expand All @@ -369,11 +402,12 @@ where
}

/// Extend a hash map with copied items from a parallel iterator.
impl<'a, K, V, S> ParallelExtend<(&'a K, &'a V)> for HashMap<K, V, S>
impl<'a, K, V, S, A> ParallelExtend<(&'a K, &'a V)> for HashMap<K, V, S, A>
where
K: Copy + Eq + Hash + Sync,
V: Copy + Sync,
S: BuildHasher,
A: AllocRef + Clone,
{
fn par_extend<I>(&mut self, par_iter: I)
where
Expand All @@ -384,12 +418,13 @@ where
}

// This is equal to the normal `HashMap` -- no custom advantage.
fn extend<K, V, S, I>(map: &mut HashMap<K, V, S>, par_iter: I)
fn extend<K, V, S, A, I>(map: &mut HashMap<K, V, S, A>, par_iter: I)
where
K: Eq + Hash,
S: BuildHasher,
I: IntoParallelIterator,
HashMap<K, V, S>: Extend<I::Item>,
A: AllocRef + Clone,
HashMap<K, V, S, A>: Extend<I::Item>,
{
let (list, len) = super::helpers::collect(par_iter);

Expand Down
Loading