spacetimedb_data_structures/
map.rs

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