1use core::any::TypeId;
20use core::hash::{BuildHasher, Hash, Hasher};
21
22use hashbrown::{HashMap, HashSet};
23
24use crate::entity::Entity;
25
26#[derive(Clone, Copy, Debug, Default)]
28pub struct NoOpHash;
29
30impl BuildHasher for NoOpHash {
31 type Hasher = NoOpHasher;
32
33 fn build_hasher(&self) -> Self::Hasher {
34 NoOpHasher(0)
35 }
36}
37
38#[derive(Debug, Default)]
40pub struct NoOpHasher(u64);
41
42impl Hasher for NoOpHasher {
43 fn finish(&self) -> u64 {
44 self.0
45 }
46
47 fn write(&mut self, bytes: &[u8]) {
48 self.0 = bytes.iter().fold(self.0, |hash, byte| {
50 hash.rotate_left(8).wrapping_add(*byte as u64)
51 });
52 }
53
54 fn write_u64(&mut self, value: u64) {
55 self.0 = value;
56 }
57}
58
59#[derive(Clone, Copy, Debug, Default)]
61pub struct EntityHash;
62
63impl BuildHasher for EntityHash {
64 type Hasher = EntityHasher;
65
66 fn build_hasher(&self) -> Self::Hasher {
67 EntityHasher(0)
68 }
69}
70
71#[derive(Debug, Default)]
78pub struct EntityHasher(u64);
79
80impl Hasher for EntityHasher {
81 fn finish(&self) -> u64 {
82 self.0
83 }
84
85 fn write(&mut self, _bytes: &[u8]) {
86 panic!("EntityHasher only hashes u64 keys");
87 }
88
89 fn write_u64(&mut self, bits: u64) {
90 const UPPER_PHI: u64 = 0x9e37_79b9_0000_0001;
91 self.0 = bits.wrapping_mul(UPPER_PHI);
92 }
93}
94
95impl Hash for Entity {
96 fn hash<H: Hasher>(&self, state: &mut H) {
97 state.write_u64(self.to_bits());
98 }
99}
100
101pub type TypeIdHashMap<V> = HashMap<TypeId, V, NoOpHash>;
103
104pub type TypeIdHashSet = HashSet<TypeId, NoOpHash>;
106
107pub type EntityHashMap<V> = HashMap<Entity, V, EntityHash>;
109
110pub type EntityHashSet = HashSet<Entity, EntityHash>;
112#[cfg(test)]
113mod tests {
114 use super::*;
115 use core::hash::BuildHasher;
116
117 #[test]
118 fn the_no_op_hasher_passes_u64_through() {
119 let mut hasher = NoOpHash.build_hasher();
120 hasher.write_u64(0x1234_5678_9abc_def0);
121 assert_eq!(hasher.finish(), 0x1234_5678_9abc_def0);
122 }
123
124 #[test]
125 fn the_entity_hasher_is_a_bijection_on_indices() {
126 let mut hashes: Vec<u64> = (0..64u64)
129 .map(|index| {
130 let mut hasher = EntityHash.build_hasher();
131 hasher.write_u64(index);
132 hasher.finish()
133 })
134 .collect();
135 hashes.sort_unstable();
136 hashes.dedup();
137 assert_eq!(hashes.len(), 64, "no collisions in this range");
138 }
139
140 #[test]
141 fn entity_maps_key_by_handle() {
142 let mut map: EntityHashMap<u32> = EntityHashMap::default();
143 let a = Entity::from_raw(1, 0);
144 let b = Entity::from_raw(1, 1);
145 map.insert(a, 10);
146 map.insert(b, 20);
147 assert_eq!(map.get(&a), Some(&10));
148 assert_eq!(map.get(&b), Some(&20), "the generation is part of the key");
149 }
150
151 #[test]
152 fn type_id_maps_key_by_type() {
153 let mut map: TypeIdHashMap<&'static str> = TypeIdHashMap::default();
154 map.insert(TypeId::of::<u32>(), "u32");
155 map.insert(TypeId::of::<bool>(), "bool");
156 assert_eq!(map.get(&TypeId::of::<u32>()), Some(&"u32"));
157 assert_eq!(map.get(&TypeId::of::<bool>()), Some(&"bool"));
158 }
159}