Skip to content
Draft
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
1 change: 1 addition & 0 deletions .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
imports_layout = "Vertical"
5 changes: 4 additions & 1 deletion benches/bench.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#![expect(missing_docs)] // criterion_group! generates a public bench entrypoint

use criterion::{criterion_group, criterion_main};
use criterion::{
criterion_group,
criterion_main,
};

mod general_ops;
mod insert_unique_unchecked;
Expand Down
16 changes: 12 additions & 4 deletions benches/general_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@
//! * Hasher: std default (SipHash) and crate default (foldhash).
//! * Int key distribution: low bit heavy, top bit heavy, and random.
//! * Task: basic functionality: insert, insert_erase, lookup, lookup_fail, iter
use criterion::Criterion;
use hashbrown::DefaultHashBuilder;
use hashbrown::{HashMap, HashSet};

use std::{
hash::RandomState,
hint::black_box,
sync::atomic::{self, AtomicUsize},
sync::atomic::{
self,
AtomicUsize,
},
};

use criterion::Criterion;
use hashbrown::{
DefaultHashBuilder,
HashMap,
HashSet,
};

const SIZE: usize = 1000;
Expand Down
4 changes: 3 additions & 1 deletion benches/insert_unique_unchecked.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! Compare `insert` and `insert_unique_unchecked` operations performance.

use std::hint::black_box;

use criterion::Criterion;
use hashbrown::HashMap;
use std::hint::black_box;

pub(crate) fn register_benches(c: &mut Criterion) {
let keys: Vec<String> = (0..1000).map(|i| format!("xxxx{i}yyyy")).collect();
Expand Down
1 change: 1 addition & 0 deletions benches/set_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//!
//! Each assigning test is done in the configuration that is faster. Cheating, I know.
//! The exception to this is Sub, because there the result differs. So I made two benchmarks for Sub.

use criterion::Criterion;
use hashbrown::HashSet;

Expand Down
3 changes: 2 additions & 1 deletion benches/with_capacity.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::hint::black_box;

use criterion::Criterion;
use hashbrown::HashMap;
use std::hint::black_box;

type Map<K, V> = HashMap<K, V>;

Expand Down
42 changes: 32 additions & 10 deletions src/alloc.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
#[cfg(test)]
pub(crate) use self::inner::AllocError;
pub(crate) use self::inner::{Allocator, Global, do_alloc};
pub(crate) use self::inner::{
Allocator,
Global,
do_alloc,
};

// Nightly-case.
// Use unstable `allocator_api` feature.
// This is compatible with `allocator-api2` which can be enabled or not.
// This is used when building for `std`.
#[cfg(feature = "nightly")]
mod inner {
use core::alloc::Layout;
use core::ptr::NonNull;
use core::{
alloc::Layout,
ptr::NonNull,
};

#[cfg(test)]
pub(crate) use stdalloc::alloc::AllocError;
pub(crate) use stdalloc::alloc::{Allocator, Global};
pub(crate) use stdalloc::alloc::{
Allocator,
Global,
};

pub(crate) fn do_alloc<A: Allocator>(alloc: &A, layout: Layout) -> Result<NonNull<[u8]>, ()> {
match alloc.allocate(layout) {
Expand All @@ -30,11 +40,17 @@ mod inner {
// `core::alloc::Allocator`.
#[cfg(all(not(feature = "nightly"), feature = "allocator-api2"))]
mod inner {
use core::{
alloc::Layout,
ptr::NonNull,
};

#[cfg(test)]
pub(crate) use allocator_api2::alloc::AllocError;
pub(crate) use allocator_api2::alloc::{Allocator, Global};
use core::alloc::Layout;
use core::ptr::NonNull;
pub(crate) use allocator_api2::alloc::{
Allocator,
Global,
};

pub(crate) fn do_alloc<A: Allocator>(alloc: &A, layout: Layout) -> Result<NonNull<[u8]>, ()> {
match alloc.allocate(layout) {
Expand All @@ -54,9 +70,15 @@ mod inner {
// or `nightly` without disturbing users that don't want to use it.
#[cfg(not(any(feature = "nightly", feature = "allocator-api2")))]
mod inner {
use core::alloc::Layout;
use core::ptr::NonNull;
use stdalloc::alloc::{alloc, dealloc};
use core::{
alloc::Layout,
ptr::NonNull,
};

use stdalloc::alloc::{
alloc,
dealloc,
};

#[expect(clippy::missing_safety_doc)] // not exposed outside of this crate
pub unsafe trait Allocator {
Expand Down
7 changes: 6 additions & 1 deletion src/control/bitmask.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
use super::group::{BITMASK_ITER_MASK, BITMASK_STRIDE, BitMaskWord, NonZeroBitMaskWord};
use super::group::{
BITMASK_ITER_MASK,
BITMASK_STRIDE,
BitMaskWord,
NonZeroBitMaskWord,
};

/// A bit mask which contains the result of a `Match` operation on a `Group` and
/// allows iterating through them.
Expand Down
6 changes: 5 additions & 1 deletion src/control/group/generic.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use super::super::{BitMask, Tag};
use core::ptr;

use super::super::{
BitMask,
Tag,
};

// Use the native word size as the group size. Using a 64-bit group size on
// a 32-bit architecture will just end up being more expensive because
// shifts and multiplies will need to be emulated.
Expand Down
11 changes: 8 additions & 3 deletions src/control/group/lsx.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
use super::super::{BitMask, Tag};
use core::num::NonZeroU16;
use core::{
arch::loongarch64::*,
num::NonZeroU16,
};

use core::arch::loongarch64::*;
use super::super::{
BitMask,
Tag,
};

pub(crate) type BitMaskWord = u16;
pub(crate) type NonZeroBitMaskWord = NonZeroU16;
Expand Down
7 changes: 6 additions & 1 deletion src/control/group/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,9 @@ cfg_select! {
}
}
pub(crate) use self::imp::Group;
pub(super) use self::imp::{BITMASK_ITER_MASK, BITMASK_STRIDE, BitMaskWord, NonZeroBitMaskWord};
pub(super) use self::imp::{
BITMASK_ITER_MASK,
BITMASK_STRIDE,
BitMaskWord,
NonZeroBitMaskWord,
};
12 changes: 9 additions & 3 deletions src/control/group/neon.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
use super::super::{BitMask, Tag};
use core::arch::aarch64 as neon;
use core::num::NonZeroU64;
use core::{
arch::aarch64 as neon,
num::NonZeroU64,
};

use super::super::{
BitMask,
Tag,
};

pub(crate) type BitMaskWord = u64;
pub(crate) type NonZeroBitMaskWord = NonZeroU64;
Expand Down
9 changes: 6 additions & 3 deletions src/control/group/sse2.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use super::super::{BitMask, Tag};
use core::num::NonZeroU16;

#[cfg(target_arch = "x86")]
use core::arch::x86;
#[cfg(target_arch = "x86_64")]
use core::arch::x86_64 as x86;
use core::num::NonZeroU16;

use super::super::{
BitMask,
Tag,
};

pub(crate) type BitMaskWord = u16;
pub(crate) type NonZeroBitMaskWord = NonZeroU16;
Expand Down
5 changes: 4 additions & 1 deletion src/control/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@ use self::bitmask::BitMask;
pub(crate) use self::{
bitmask::BitMaskIter,
group::Group,
tag::{Tag, TagSliceExt},
tag::{
Tag,
TagSliceExt,
},
};
5 changes: 4 additions & 1 deletion src/control/tag.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use core::{fmt, mem};
use core::{
fmt,
mem,
};

/// Single tag in a control group.
#[derive(Copy, Clone, PartialEq, Eq)]
Expand Down
5 changes: 4 additions & 1 deletion src/external_trait_impls/rayon/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use stdalloc::collections::LinkedList;
use stdalloc::vec::Vec;

use rayon::iter::{IntoParallelIterator, ParallelIterator};
use rayon::iter::{
IntoParallelIterator,
ParallelIterator,
};

/// Helper for collecting parallel iterators to an intermediary
#[expect(clippy::linkedlist)] // yes, we need linked list here for efficient appending!
Expand Down
52 changes: 41 additions & 11 deletions src/external_trait_impls/rayon/map.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,35 @@
//! Rayon extensions for `HashMap`.

use super::raw::{RawIntoParIter, RawParDrain, RawParIter};
use crate::HashMap;
use crate::alloc::{Allocator, Global};
use core::fmt;
use core::hash::{BuildHasher, Hash};
use core::marker::PhantomData;
use rayon::iter::plumbing::UnindexedConsumer;
use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelExtend, ParallelIterator};
use core::{
fmt,
hash::{
BuildHasher,
Hash,
},
marker::PhantomData,
};

use rayon::iter::{
FromParallelIterator,
IntoParallelIterator,
ParallelExtend,
ParallelIterator,
plumbing::UnindexedConsumer,
};

use crate::{
HashMap,
alloc::{
Allocator,
Global,
},
};

use super::raw::{
RawIntoParIter,
RawParDrain,
RawParIter,
};

/// Parallel iterator over shared references to entries in a map.
///
Expand Down Expand Up @@ -456,11 +478,19 @@ where

#[cfg(test)]
mod test_par_map {
use core::hash::{Hash, Hasher};
use core::sync::atomic::{AtomicUsize, Ordering};
use stdalloc::vec::Vec;
use core::{
hash::{
Hash,
Hasher,
},
sync::atomic::{
AtomicUsize,
Ordering,
},
};

use rayon::prelude::*;
use stdalloc::vec::Vec;

use crate::HashMap;

Expand Down
33 changes: 26 additions & 7 deletions src/external_trait_impls/rayon/raw.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
use crate::alloc::{Allocator, Global};
use crate::raw::{Bucket, RawIter, RawIterRange, RawTable};
use crate::scopeguard::guard;
use core::marker::PhantomData;
use core::mem;
use core::ptr::NonNull;
use core::{
marker::PhantomData,
mem,
ptr::NonNull,
};

use rayon::iter::{
ParallelIterator,
plumbing::{self, Folder, UnindexedConsumer, UnindexedProducer},
plumbing::{
self,
Folder,
UnindexedConsumer,
UnindexedProducer,
},
};

use crate::{
alloc::{
Allocator,
Global,
},
raw::{
Bucket,
RawIter,
RawIterRange,
RawTable,
},
scopeguard::guard,
};

/// Parallel iterator which returns a raw pointer to every full bucket in the table.
Expand Down
Loading
Loading