spacetimedb_data_structures/
map.rs

1use core::hash::{BuildHasher, BuildHasherDefault};
2pub use hashbrown::hash_map::Entry;
3use nohash_hasher::BuildNoHashHasher;
4pub use nohash_hasher::IsEnabled as ValidAsIdentityHash;
5
6pub type DefaultHashBuilder = BuildHasherDefault<ahash::AHasher>;
7// TODO(centril): expose two maps instead,
8// one `map::fast::HashMap` and one `map::ddos::HashMap`.
9// In the first case we won't care about DDoS protection at all and can use `foldhash::fast`.
10// In the lattr, we can use e.g., randomized AHash.
11pub type HashMap<K, V, S = DefaultHashBuilder> = hashbrown::HashMap<K, V, S>;
12pub type HashSet<T, S = DefaultHashBuilder> = hashbrown::HashSet<T, S>;
13
14/// A version of [`HashMap<K, V>`] using the identity hash function,
15/// which is valid for any key type that can be converted to a `u64` without truncation.
16pub type IntMap<K, V> = HashMap<K, V, BuildNoHashHasher<K>>;
17
18/// A version of [`HashSet<K>`] using the identity hash function,
19/// which is valid for any key type that can be converted to a `u64` without truncation.
20pub type IntSet<K> = HashSet<K, BuildNoHashHasher<K>>;
21
22pub trait HashCollectionExt {
23    /// Returns a new collection with default capacity, using `S::default()` to build the hasher.
24    fn new() -> Self;
25
26    /// Returns a new collection with `capacity`, using `S::default()` to build the hasher.
27    fn with_capacity(capacity: usize) -> Self;
28}
29
30impl<K, V, S: BuildHasher + Default> HashCollectionExt for HashMap<K, V, S> {
31    fn new() -> Self {
32        HashMap::with_hasher(S::default())
33    }
34
35    fn with_capacity(capacity: usize) -> Self {
36        HashMap::with_capacity_and_hasher(capacity, S::default())
37    }
38}
39
40impl<K, S: BuildHasher + Default> HashCollectionExt for HashSet<K, S> {
41    fn new() -> Self {
42        HashSet::with_hasher(S::default())
43    }
44
45    fn with_capacity(capacity: usize) -> Self {
46        HashSet::with_capacity_and_hasher(capacity, S::default())
47    }
48}