Skip to content

Commit 4c824c5

Browse files
committed
Auto merge of #533 - Amanieu:default-hasher, r=Amanieu
Replace "ahash" with "default-hasher" in Cargo features This allows us to change the default hasher in the future without it being a breaking change.
2 parents f0eece4 + 268414b commit 4c824c5

File tree

10 files changed

+172
-195
lines changed

10 files changed

+172
-195
lines changed

Cargo.toml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ serde = { version = "1.0.25", default-features = false, optional = true }
2222
rkyv = { version = "0.7.42", optional = true, default-features = false, features = [
2323
"alloc",
2424
] }
25+
borsh = { version = "1.5.0", default-features = false, optional = true, features = ["derive"]}
2526

2627
# When built as part of libstd
2728
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
@@ -36,9 +37,6 @@ allocator-api2 = { version = "0.2.9", optional = true, default-features = false,
3637
# Equivalent trait which can be shared with other hash table implementations.
3738
equivalent = { version = "1.0", optional = true, default-features = false }
3839

39-
# borsh serde
40-
borsh = { version = "1.5.0", default-features = false, optional = true, features = ["derive"]}
41-
4240
[dev-dependencies]
4341
lazy_static = "1.4"
4442
rand = { version = "0.8.3", features = ["small_rng"] }
@@ -50,27 +48,37 @@ bumpalo = { version = "3.13.0", features = ["allocator-api2"] }
5048
rkyv = { version = "0.7.42", features = ["validation"] }
5149

5250
[features]
53-
default = ["ahash", "inline-more", "allocator-api2", "equivalent"]
51+
default = ["default-hasher", "inline-more", "allocator-api2", "equivalent"]
5452

53+
# Enables use of nightly features. This is only guaranteed to work on the latest
54+
# version of nightly Rust.
5555
nightly = ["allocator-api2?/nightly", "bumpalo/allocator_api"]
5656

57+
# Enables the RustcEntry API used to provide the standard library's Entry API.
5758
rustc-internal-api = []
59+
60+
# Internal feature used when building as part of the standard library.
5861
rustc-dep-of-std = [
5962
"nightly",
6063
"core",
6164
"compiler_builtins",
6265
"alloc",
6366
"rustc-internal-api",
6467
]
68+
69+
# Enables the RawTable API.
6570
raw = []
6671

72+
# Provides a default hasher. Currently this is AHash but this is subject to
73+
# change in the future. Note that the default hasher does *not* provide HashDoS
74+
# resistance, unlike the one in the standard library.
75+
default-hasher = ["dep:ahash"]
76+
6777
# Enables usage of `#[inline]` on far more functions than by default in this
6878
# crate. This may lead to a performance increase but often comes at a compile
6979
# time cost.
7080
inline-more = []
7181

72-
borsh = ["dep:borsh"]
73-
7482
[package.metadata.docs.rs]
7583
features = ["nightly", "rayon", "serde", "raw"]
7684
rustdoc-args = ["--generate-link-to-definition"]

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,14 @@ This crate has the following Cargo features:
101101

102102
- `nightly`: Enables nightly-only features including: `#[may_dangle]`.
103103
- `serde`: Enables serde serialization support.
104+
- `borsh`: Enables borsh serialization support.
104105
- `rkyv`: Enables rkyv serialization support.
105106
- `rayon`: Enables rayon parallel iterator support.
107+
- `equivalent`: Allows comparisons to be customized with the `Equivalent` trait.
106108
- `raw`: Enables access to the experimental and unsafe `RawTable` API.
107109
- `inline-more`: Adds inline hints to most functions, improving run-time performance at the cost
108110
of compilation time. (enabled by default)
109-
- `ahash`: Compiles with ahash as default hasher. (enabled by default)
111+
- `default-hasher`: Compiles with ahash as default hasher. (enabled by default)
110112
- `allocator-api2`: Enables support for allocators that support `allocator-api2`. (enabled by default)
111113

112114
## License

benches/bench.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ extern crate test;
88

99
use test::{black_box, Bencher};
1010

11-
use hashbrown::hash_map::DefaultHashBuilder;
11+
use hashbrown::DefaultHashBuilder;
1212
use hashbrown::{HashMap, HashSet};
1313
use std::{
1414
collections::hash_map::RandomState,

src/external_trait_impls/rayon/table.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,7 @@ mod test_par_table {
215215

216216
use rayon::prelude::*;
217217

218-
use crate::{
219-
hash_map::{make_hash, DefaultHashBuilder},
220-
hash_table::HashTable,
221-
};
218+
use crate::{hash_map::make_hash, hash_table::HashTable, DefaultHashBuilder};
222219

223220
#[test]
224221
fn test_iterate() {

src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@
3939
#![cfg_attr(feature = "nightly", warn(fuzzy_provenance_casts))]
4040
#![cfg_attr(feature = "nightly", allow(internal_features))]
4141

42+
/// Default hasher for [`HashMap`], [`HashSet`] and [`HashTable`].
43+
#[cfg(feature = "default-hasher")]
44+
pub type DefaultHashBuilder = core::hash::BuildHasherDefault<ahash::AHasher>;
45+
46+
/// Dummy default hasher for [`HashMap`], [`HashSet`] and [`HashTable`].
47+
#[cfg(not(feature = "default-hasher"))]
48+
pub enum DefaultHashBuilder {}
49+
4250
#[cfg(test)]
4351
#[macro_use]
4452
extern crate std;

src/map.rs

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::raw::{
22
Allocator, Bucket, Global, RawDrain, RawExtractIf, RawIntoIter, RawIter, RawTable,
33
};
4-
use crate::{Equivalent, TryReserveError};
4+
use crate::{DefaultHashBuilder, Equivalent, TryReserveError};
55
use core::borrow::Borrow;
66
use core::fmt::{self, Debug};
77
use core::hash::{BuildHasher, Hash};
@@ -10,14 +10,6 @@ use core::marker::PhantomData;
1010
use core::mem;
1111
use core::ops::Index;
1212

13-
/// Default hasher for `HashMap`.
14-
#[cfg(feature = "ahash")]
15-
pub type DefaultHashBuilder = core::hash::BuildHasherDefault<ahash::AHasher>;
16-
17-
/// Dummy default hasher for `HashMap`.
18-
#[cfg(not(feature = "ahash"))]
19-
pub enum DefaultHashBuilder {}
20-
2113
/// A hash map implemented with quadratic probing and SIMD lookup.
2214
///
2315
/// The default hashing algorithm is currently [`AHash`], though this is
@@ -262,7 +254,7 @@ where
262254
hash_builder.hash_one(val)
263255
}
264256

265-
#[cfg(feature = "ahash")]
257+
#[cfg(feature = "default-hasher")]
266258
impl<K, V> HashMap<K, V, DefaultHashBuilder> {
267259
/// Creates an empty `HashMap`.
268260
///
@@ -325,7 +317,7 @@ impl<K, V> HashMap<K, V, DefaultHashBuilder> {
325317
}
326318
}
327319

328-
#[cfg(feature = "ahash")]
320+
#[cfg(feature = "default-hasher")]
329321
impl<K, V, A: Allocator> HashMap<K, V, DefaultHashBuilder, A> {
330322
/// Creates an empty `HashMap` using the given allocator.
331323
///
@@ -447,7 +439,7 @@ impl<K, V, S> HashMap<K, V, S> {
447439
///
448440
/// ```
449441
/// use hashbrown::HashMap;
450-
/// use hashbrown::hash_map::DefaultHashBuilder;
442+
/// use hashbrown::DefaultHashBuilder;
451443
///
452444
/// let s = DefaultHashBuilder::default();
453445
/// let mut map = HashMap::with_hasher(s);
@@ -489,7 +481,7 @@ impl<K, V, S> HashMap<K, V, S> {
489481
///
490482
/// ```
491483
/// use hashbrown::HashMap;
492-
/// use hashbrown::hash_map::DefaultHashBuilder;
484+
/// use hashbrown::DefaultHashBuilder;
493485
///
494486
/// let s = DefaultHashBuilder::default();
495487
/// let mut map = HashMap::with_capacity_and_hasher(10, s);
@@ -535,7 +527,7 @@ impl<K, V, S, A: Allocator> HashMap<K, V, S, A> {
535527
///
536528
/// ```
537529
/// use hashbrown::HashMap;
538-
/// use hashbrown::hash_map::DefaultHashBuilder;
530+
/// use hashbrown::DefaultHashBuilder;
539531
///
540532
/// let s = DefaultHashBuilder::default();
541533
/// let mut map = HashMap::with_hasher(s);
@@ -570,7 +562,7 @@ impl<K, V, S, A: Allocator> HashMap<K, V, S, A> {
570562
///
571563
/// ```
572564
/// use hashbrown::HashMap;
573-
/// use hashbrown::hash_map::DefaultHashBuilder;
565+
/// use hashbrown::DefaultHashBuilder;
574566
///
575567
/// let s = DefaultHashBuilder::default();
576568
/// let mut map = HashMap::with_capacity_and_hasher(10, s);
@@ -592,7 +584,7 @@ impl<K, V, S, A: Allocator> HashMap<K, V, S, A> {
592584
///
593585
/// ```
594586
/// use hashbrown::HashMap;
595-
/// use hashbrown::hash_map::DefaultHashBuilder;
587+
/// use hashbrown::DefaultHashBuilder;
596588
///
597589
/// let hasher = DefaultHashBuilder::default();
598590
/// let map: HashMap<i32, i32> = HashMap::with_hasher(hasher);
@@ -2258,7 +2250,7 @@ where
22582250
}
22592251

22602252
// The default hasher is used to match the std implementation signature
2261-
#[cfg(feature = "ahash")]
2253+
#[cfg(feature = "default-hasher")]
22622254
impl<K, V, A, const N: usize> From<[(K, V); N]> for HashMap<K, V, DefaultHashBuilder, A>
22632255
where
22642256
K: Eq + Hash,
@@ -6726,7 +6718,6 @@ mod test_map {
67266718
use rand::{rngs::SmallRng, Rng, SeedableRng};
67276719
use std::borrow::ToOwned;
67286720
use std::cell::RefCell;
6729-
use std::usize;
67306721
use std::vec::Vec;
67316722

67326723
#[test]

src/raw/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ impl<T> Bucket<T> {
483483
/// use core::hash::{BuildHasher, Hash};
484484
/// use hashbrown::raw::{Bucket, RawTable};
485485
///
486-
/// type NewHashBuilder = core::hash::BuildHasherDefault<ahash::AHasher>;
486+
/// type NewHashBuilder = hashbrown::DefaultHashBuilder;
487487
///
488488
/// fn make_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
489489
/// use core::hash::Hasher;
@@ -649,7 +649,7 @@ impl<T> Bucket<T> {
649649
/// use core::hash::{BuildHasher, Hash};
650650
/// use hashbrown::raw::{Bucket, RawTable};
651651
///
652-
/// type NewHashBuilder = core::hash::BuildHasherDefault<ahash::AHasher>;
652+
/// type NewHashBuilder = hashbrown::DefaultHashBuilder;
653653
///
654654
/// fn make_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
655655
/// use core::hash::Hasher;
@@ -708,7 +708,7 @@ impl<T> Bucket<T> {
708708
/// use core::hash::{BuildHasher, Hash};
709709
/// use hashbrown::raw::{Bucket, RawTable};
710710
///
711-
/// type NewHashBuilder = core::hash::BuildHasherDefault<ahash::AHasher>;
711+
/// type NewHashBuilder = hashbrown::DefaultHashBuilder;
712712
///
713713
/// fn make_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
714714
/// use core::hash::Hasher;
@@ -1235,7 +1235,7 @@ impl<T, A: Allocator> RawTable<T, A> {
12351235
fallibility,
12361236
Self::TABLE_LAYOUT,
12371237
if T::NEEDS_DROP {
1238-
Some(mem::transmute(ptr::drop_in_place::<T> as unsafe fn(*mut T)))
1238+
Some(|ptr| ptr::drop_in_place(ptr as *mut T))
12391239
} else {
12401240
None
12411241
},
@@ -2911,7 +2911,7 @@ impl RawTableInner {
29112911
hasher: &dyn Fn(&mut Self, usize) -> u64,
29122912
fallibility: Fallibility,
29132913
layout: TableLayout,
2914-
drop: Option<fn(*mut u8)>,
2914+
drop: Option<unsafe fn(*mut u8)>,
29152915
) -> Result<(), TryReserveError>
29162916
where
29172917
A: Allocator,
@@ -3145,7 +3145,7 @@ impl RawTableInner {
31453145
&mut self,
31463146
hasher: &dyn Fn(&mut Self, usize) -> u64,
31473147
size_of: usize,
3148-
drop: Option<fn(*mut u8)>,
3148+
drop: Option<unsafe fn(*mut u8)>,
31493149
) {
31503150
// If the hash function panics then properly clean up any elements
31513151
// that we haven't rehashed yet. We unfortunately can't preserve the
@@ -4577,7 +4577,7 @@ mod test_map {
45774577
&|table, index| hasher(table.bucket::<T>(index).as_ref()),
45784578
mem::size_of::<T>(),
45794579
if mem::needs_drop::<T>() {
4580-
Some(mem::transmute(ptr::drop_in_place::<T> as unsafe fn(*mut T)))
4580+
Some(|ptr| ptr::drop_in_place(ptr as *mut T))
45814581
} else {
45824582
None
45834583
},

src/set.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ use core::hash::{BuildHasher, Hash};
77
use core::iter::{Chain, FusedIterator};
88
use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign};
99

10-
use super::map::{self, DefaultHashBuilder, HashMap, Keys};
10+
use super::map::{self, HashMap, Keys};
1111
use crate::raw::{Allocator, Global, RawExtractIf};
12+
use crate::DefaultHashBuilder;
1213

1314
// Future Optimization (FIXME!)
1415
// =============================
@@ -128,7 +129,7 @@ impl<T: Clone, S: Clone, A: Allocator + Clone> Clone for HashSet<T, S, A> {
128129
}
129130
}
130131

131-
#[cfg(feature = "ahash")]
132+
#[cfg(feature = "default-hasher")]
132133
impl<T> HashSet<T, DefaultHashBuilder> {
133134
/// Creates an empty `HashSet`.
134135
///
@@ -192,7 +193,7 @@ impl<T> HashSet<T, DefaultHashBuilder> {
192193
}
193194
}
194195

195-
#[cfg(feature = "ahash")]
196+
#[cfg(feature = "default-hasher")]
196197
impl<T: Hash + Eq, A: Allocator> HashSet<T, DefaultHashBuilder, A> {
197198
/// Creates an empty `HashSet`.
198199
///
@@ -459,7 +460,7 @@ impl<T, S> HashSet<T, S, Global> {
459460
///
460461
/// ```
461462
/// use hashbrown::HashSet;
462-
/// use hashbrown::hash_map::DefaultHashBuilder;
463+
/// use hashbrown::DefaultHashBuilder;
463464
///
464465
/// let s = DefaultHashBuilder::default();
465466
/// let mut set = HashSet::with_hasher(s);
@@ -497,7 +498,7 @@ impl<T, S> HashSet<T, S, Global> {
497498
///
498499
/// ```
499500
/// use hashbrown::HashSet;
500-
/// use hashbrown::hash_map::DefaultHashBuilder;
501+
/// use hashbrown::DefaultHashBuilder;
501502
///
502503
/// let s = DefaultHashBuilder::default();
503504
/// let mut set = HashSet::with_capacity_and_hasher(10, s);
@@ -546,7 +547,7 @@ where
546547
///
547548
/// ```
548549
/// use hashbrown::HashSet;
549-
/// use hashbrown::hash_map::DefaultHashBuilder;
550+
/// use hashbrown::DefaultHashBuilder;
550551
///
551552
/// let s = DefaultHashBuilder::default();
552553
/// let mut set = HashSet::with_hasher(s);
@@ -584,7 +585,7 @@ where
584585
///
585586
/// ```
586587
/// use hashbrown::HashSet;
587-
/// use hashbrown::hash_map::DefaultHashBuilder;
588+
/// use hashbrown::DefaultHashBuilder;
588589
///
589590
/// let s = DefaultHashBuilder::default();
590591
/// let mut set = HashSet::with_capacity_and_hasher(10, s);
@@ -605,7 +606,7 @@ where
605606
///
606607
/// ```
607608
/// use hashbrown::HashSet;
608-
/// use hashbrown::hash_map::DefaultHashBuilder;
609+
/// use hashbrown::DefaultHashBuilder;
609610
///
610611
/// let hasher = DefaultHashBuilder::default();
611612
/// let set: HashSet<i32> = HashSet::with_hasher(hasher);
@@ -1324,7 +1325,7 @@ where
13241325
}
13251326

13261327
// The default hasher is used to match the std implementation signature
1327-
#[cfg(feature = "ahash")]
1328+
#[cfg(feature = "default-hasher")]
13281329
impl<T, A, const N: usize> From<[T; N]> for HashSet<T, DefaultHashBuilder, A>
13291330
where
13301331
T: Eq + Hash,
@@ -2643,8 +2644,8 @@ fn assert_covariance() {
26432644

26442645
#[cfg(test)]
26452646
mod test_set {
2646-
use super::super::map::DefaultHashBuilder;
26472647
use super::HashSet;
2648+
use crate::DefaultHashBuilder;
26482649
use std::vec::Vec;
26492650

26502651
#[test]

0 commit comments

Comments
 (0)