Skip to content

Commit

Permalink
Auto merge of #468 - JustForFun88:make_alloc_not_clone, r=Amanieu
Browse files Browse the repository at this point in the history
Make allocator not `Clone`

`@Amanieu` Implements the idea proposed in #465 (comment). The `A: Allocator + Clone` requirement remains only for `Clone` implementations.

~~**The pull request is basically complete, just a final review (and maybe some tweaks if needed). Also, I haven't documented the functions yet. This can be done after the initial approval of this pull request.**~~

Main changes made:
1. Allacator moved from `RawTableInner` to `RawTable`;
2. `IS_ZERO_SIZED_TYPE` and `DATA_NEEDS_DROP` constants moved from separate structures to `SizedTypeProperties` trait;
3. For ease of implementation and avoidance of duplication, some functions are downgraded from `RawTable` to `RawTableInner`. These are: `with_capacity`, `iter`, `drop_elements`. Additionally, the `drop_inner_table` function has been created through which `impl Drop for RawTable<T, A>` is now implemented.
  • Loading branch information
bors committed Sep 5, 2023
2 parents a33acbe + 91d3675 commit fe81cad
Show file tree
Hide file tree
Showing 8 changed files with 776 additions and 448 deletions.
40 changes: 15 additions & 25 deletions src/external_trait_impls/rayon/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,11 @@ impl<K: Eq + Hash, V: fmt::Debug> fmt::Debug for ParValuesMut<'_, K, V> {
/// [`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, A: Allocator + Clone = Global> {
pub struct IntoParIter<K, V, A: Allocator = Global> {
inner: RawIntoParIter<(K, V), A>,
}

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

#[cfg_attr(feature = "inline-more", inline)]
Expand All @@ -248,9 +248,7 @@ impl<K: Send, V: Send, A: Allocator + Clone + Send> ParallelIterator for IntoPar
}
}

impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, A: Allocator + Clone> fmt::Debug
for IntoParIter<K, V, A>
{
impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, A: Allocator> fmt::Debug for IntoParIter<K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
ParIter {
inner: unsafe { self.inner.par_iter() },
Expand All @@ -267,11 +265,11 @@ impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, A: Allocator + Clone> fmt::Debug
///
/// [`par_drain`]: /hashbrown/struct.HashMap.html#method.par_drain
/// [`HashMap`]: /hashbrown/struct.HashMap.html
pub struct ParDrain<'a, K, V, A: Allocator + Clone = Global> {
pub struct ParDrain<'a, K, V, A: Allocator = Global> {
inner: RawParDrain<'a, (K, V), A>,
}

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

#[cfg_attr(feature = "inline-more", inline)]
Expand All @@ -283,9 +281,7 @@ impl<K: Send, V: Send, A: Allocator + Clone + Sync> ParallelIterator for ParDrai
}
}

impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, A: Allocator + Clone> fmt::Debug
for ParDrain<'_, K, V, A>
{
impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, A: Allocator> fmt::Debug for ParDrain<'_, K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
ParIter {
inner: unsafe { self.inner.par_iter() },
Expand All @@ -295,7 +291,7 @@ impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, A: Allocator + Clone> fmt::Debug
}
}

impl<K: Sync, V: Sync, S, A: Allocator + Clone> HashMap<K, V, S, A> {
impl<K: Sync, V: Sync, S, A: Allocator> 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> {
Expand All @@ -315,7 +311,7 @@ impl<K: Sync, V: Sync, S, A: Allocator + Clone> HashMap<K, V, S, A> {
}
}

impl<K: Send, V: Send, S, A: Allocator + Clone> HashMap<K, V, S, A> {
impl<K: Send, V: Send, S, A: Allocator> 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> {
Expand All @@ -340,7 +336,7 @@ where
K: Eq + Hash + Sync,
V: PartialEq + Sync,
S: BuildHasher + Sync,
A: Allocator + Clone + Sync,
A: Allocator + 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 @@ -354,9 +350,7 @@ where
}
}

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

Expand All @@ -368,9 +362,7 @@ impl<K: Send, V: Send, S, A: Allocator + Clone + Send> IntoParallelIterator
}
}

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

Expand All @@ -383,9 +375,7 @@ impl<'a, K: Sync, V: Sync, S, A: Allocator + Clone> IntoParallelIterator
}
}

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

Expand Down Expand Up @@ -424,7 +414,7 @@ where
K: Eq + Hash + Send,
V: Send,
S: BuildHasher,
A: Allocator + Clone,
A: Allocator,
{
fn par_extend<I>(&mut self, par_iter: I)
where
Expand All @@ -440,7 +430,7 @@ where
K: Copy + Eq + Hash + Sync,
V: Copy + Sync,
S: BuildHasher,
A: Allocator + Clone,
A: Allocator,
{
fn par_extend<I>(&mut self, par_iter: I)
where
Expand All @@ -456,7 +446,7 @@ where
K: Eq + Hash,
S: BuildHasher,
I: IntoParallelIterator,
A: Allocator + Clone,
A: Allocator,
HashMap<K, V, S, A>: Extend<I::Item>,
{
let (list, len) = super::helpers::collect(par_iter);
Expand Down
18 changes: 9 additions & 9 deletions src/external_trait_impls/rayon/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,18 @@ impl<T> UnindexedProducer for ParIterProducer<T> {
}

/// Parallel iterator which consumes a table and returns elements.
pub struct RawIntoParIter<T, A: Allocator + Clone = Global> {
pub struct RawIntoParIter<T, A: Allocator = Global> {
table: RawTable<T, A>,
}

impl<T, A: Allocator + Clone> RawIntoParIter<T, A> {
impl<T, A: Allocator> RawIntoParIter<T, A> {
#[cfg_attr(feature = "inline-more", inline)]
pub(super) unsafe fn par_iter(&self) -> RawParIter<T> {
self.table.par_iter()
}
}

impl<T: Send, A: Allocator + Clone + Send> ParallelIterator for RawIntoParIter<T, A> {
impl<T: Send, A: Allocator + Send> ParallelIterator for RawIntoParIter<T, A> {
type Item = T;

#[cfg_attr(feature = "inline-more", inline)]
Expand All @@ -108,23 +108,23 @@ impl<T: Send, A: Allocator + Clone + Send> ParallelIterator for RawIntoParIter<T
}

/// Parallel iterator which consumes elements without freeing the table storage.
pub struct RawParDrain<'a, T, A: Allocator + Clone = Global> {
pub struct RawParDrain<'a, T, A: Allocator = Global> {
// We don't use a &'a mut RawTable<T> because we want RawParDrain to be
// covariant over T.
table: NonNull<RawTable<T, A>>,
marker: PhantomData<&'a RawTable<T, A>>,
}

unsafe impl<T: Send, A: Allocator + Clone> Send for RawParDrain<'_, T, A> {}
unsafe impl<T: Send, A: Allocator> Send for RawParDrain<'_, T, A> {}

impl<T, A: Allocator + Clone> RawParDrain<'_, T, A> {
impl<T, A: Allocator> RawParDrain<'_, T, A> {
#[cfg_attr(feature = "inline-more", inline)]
pub(super) unsafe fn par_iter(&self) -> RawParIter<T> {
self.table.as_ref().par_iter()
}
}

impl<T: Send, A: Allocator + Clone> ParallelIterator for RawParDrain<'_, T, A> {
impl<T: Send, A: Allocator> ParallelIterator for RawParDrain<'_, T, A> {
type Item = T;

#[cfg_attr(feature = "inline-more", inline)]
Expand All @@ -142,7 +142,7 @@ impl<T: Send, A: Allocator + Clone> ParallelIterator for RawParDrain<'_, T, A> {
}
}

impl<T, A: Allocator + Clone> Drop for RawParDrain<'_, T, A> {
impl<T, A: Allocator> Drop for RawParDrain<'_, T, A> {
fn drop(&mut self) {
// If drive_unindexed is not called then simply clear the table.
unsafe {
Expand Down Expand Up @@ -203,7 +203,7 @@ impl<T> Drop for ParDrainProducer<T> {
}
}

impl<T, A: Allocator + Clone> RawTable<T, A> {
impl<T, A: Allocator> RawTable<T, A> {
/// Returns a parallel iterator over the elements in a `RawTable`.
#[cfg_attr(feature = "inline-more", inline)]
pub unsafe fn par_iter(&self) -> RawParIter<T> {
Expand Down
34 changes: 17 additions & 17 deletions src/external_trait_impls/rayon/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelExtend, Pa
/// [`into_par_iter`]: /hashbrown/struct.HashSet.html#method.into_par_iter
/// [`HashSet`]: /hashbrown/struct.HashSet.html
/// [`IntoParallelIterator`]: https://docs.rs/rayon/1.0/rayon/iter/trait.IntoParallelIterator.html
pub struct IntoParIter<T, A: Allocator + Clone = Global> {
pub struct IntoParIter<T, A: Allocator = Global> {
inner: map::IntoParIter<T, (), A>,
}

impl<T: Send, A: Allocator + Clone + Send> ParallelIterator for IntoParIter<T, A> {
impl<T: Send, A: Allocator + Send> ParallelIterator for IntoParIter<T, A> {
type Item = T;

fn drive_unindexed<C>(self, consumer: C) -> C::Result
Expand All @@ -38,11 +38,11 @@ impl<T: Send, A: Allocator + Clone + Send> ParallelIterator for IntoParIter<T, A
///
/// [`par_drain`]: /hashbrown/struct.HashSet.html#method.par_drain
/// [`HashSet`]: /hashbrown/struct.HashSet.html
pub struct ParDrain<'a, T, A: Allocator + Clone = Global> {
pub struct ParDrain<'a, T, A: Allocator = Global> {
inner: map::ParDrain<'a, T, (), A>,
}

impl<T: Send, A: Allocator + Clone + Send + Sync> ParallelIterator for ParDrain<'_, T, A> {
impl<T: Send, A: Allocator + Send + Sync> ParallelIterator for ParDrain<'_, T, A> {
type Item = T;

fn drive_unindexed<C>(self, consumer: C) -> C::Result
Expand Down Expand Up @@ -85,7 +85,7 @@ impl<'a, T: Sync> ParallelIterator for ParIter<'a, T> {
///
/// [`par_difference`]: /hashbrown/struct.HashSet.html#method.par_difference
/// [`HashSet`]: /hashbrown/struct.HashSet.html
pub struct ParDifference<'a, T, S, A: Allocator + Clone = Global> {
pub struct ParDifference<'a, T, S, A: Allocator = Global> {
a: &'a HashSet<T, S, A>,
b: &'a HashSet<T, S, A>,
}
Expand All @@ -94,7 +94,7 @@ impl<'a, T, S, A> ParallelIterator for ParDifference<'a, T, S, A>
where
T: Eq + Hash + Sync,
S: BuildHasher + Sync,
A: Allocator + Clone + Sync,
A: Allocator + Sync,
{
type Item = &'a T;

Expand All @@ -118,7 +118,7 @@ where
///
/// [`par_symmetric_difference`]: /hashbrown/struct.HashSet.html#method.par_symmetric_difference
/// [`HashSet`]: /hashbrown/struct.HashSet.html
pub struct ParSymmetricDifference<'a, T, S, A: Allocator + Clone = Global> {
pub struct ParSymmetricDifference<'a, T, S, A: Allocator = Global> {
a: &'a HashSet<T, S, A>,
b: &'a HashSet<T, S, A>,
}
Expand All @@ -127,7 +127,7 @@ impl<'a, T, S, A> ParallelIterator for ParSymmetricDifference<'a, T, S, A>
where
T: Eq + Hash + Sync,
S: BuildHasher + Sync,
A: Allocator + Clone + Sync,
A: Allocator + Sync,
{
type Item = &'a T;

Expand All @@ -150,7 +150,7 @@ where
///
/// [`par_intersection`]: /hashbrown/struct.HashSet.html#method.par_intersection
/// [`HashSet`]: /hashbrown/struct.HashSet.html
pub struct ParIntersection<'a, T, S, A: Allocator + Clone = Global> {
pub struct ParIntersection<'a, T, S, A: Allocator = Global> {
a: &'a HashSet<T, S, A>,
b: &'a HashSet<T, S, A>,
}
Expand All @@ -159,7 +159,7 @@ impl<'a, T, S, A> ParallelIterator for ParIntersection<'a, T, S, A>
where
T: Eq + Hash + Sync,
S: BuildHasher + Sync,
A: Allocator + Clone + Sync,
A: Allocator + Sync,
{
type Item = &'a T;

Expand All @@ -181,7 +181,7 @@ where
///
/// [`par_union`]: /hashbrown/struct.HashSet.html#method.par_union
/// [`HashSet`]: /hashbrown/struct.HashSet.html
pub struct ParUnion<'a, T, S, A: Allocator + Clone = Global> {
pub struct ParUnion<'a, T, S, A: Allocator = Global> {
a: &'a HashSet<T, S, A>,
b: &'a HashSet<T, S, A>,
}
Expand All @@ -190,7 +190,7 @@ impl<'a, T, S, A> ParallelIterator for ParUnion<'a, T, S, A>
where
T: Eq + Hash + Sync,
S: BuildHasher + Sync,
A: Allocator + Clone + Sync,
A: Allocator + Sync,
{
type Item = &'a T;

Expand All @@ -216,7 +216,7 @@ impl<T, S, A> HashSet<T, S, A>
where
T: Eq + Hash + Sync,
S: BuildHasher + Sync,
A: Allocator + Clone + Sync,
A: Allocator + Sync,
{
/// Visits (potentially in parallel) the values representing the union,
/// i.e. all the values in `self` or `other`, without duplicates.
Expand Down Expand Up @@ -289,7 +289,7 @@ where
impl<T, S, A> HashSet<T, S, A>
where
T: Eq + Hash + Send,
A: Allocator + Clone + Send,
A: Allocator + Send,
{
/// Consumes (potentially in parallel) all values in an arbitrary order,
/// while preserving the set's allocated memory for reuse.
Expand All @@ -301,7 +301,7 @@ where
}
}

impl<T: Send, S, A: Allocator + Clone + Send> IntoParallelIterator for HashSet<T, S, A> {
impl<T: Send, S, A: Allocator + Send> IntoParallelIterator for HashSet<T, S, A> {
type Item = T;
type Iter = IntoParIter<T, A>;

Expand All @@ -313,7 +313,7 @@ impl<T: Send, S, A: Allocator + Clone + Send> IntoParallelIterator for HashSet<T
}
}

impl<'a, T: Sync, S, A: Allocator + Clone> IntoParallelIterator for &'a HashSet<T, S, A> {
impl<'a, T: Sync, S, A: Allocator> IntoParallelIterator for &'a HashSet<T, S, A> {
type Item = &'a T;
type Iter = ParIter<'a, T>;

Expand Down Expand Up @@ -374,7 +374,7 @@ fn extend<T, S, I, A>(set: &mut HashSet<T, S, A>, par_iter: I)
where
T: Eq + Hash,
S: BuildHasher,
A: Allocator + Clone,
A: Allocator,
I: IntoParallelIterator,
HashSet<T, S, A>: Extend<I::Item>,
{
Expand Down
Loading

0 comments on commit fe81cad

Please sign in to comment.