From e86db69fee83775f106f71c2599a7cefd523479b Mon Sep 17 00:00:00 2001 From: Christian Hughes Date: Tue, 3 Sep 2024 22:51:04 -0500 Subject: [PATCH] remove remnant entity hash from bevy_utils --- crates/bevy_utils/src/lib.rs | 79 ------------------------------------ 1 file changed, 79 deletions(-) diff --git a/crates/bevy_utils/src/lib.rs b/crates/bevy_utils/src/lib.rs index 772d3fda31ff3..76676de5e0fab 100644 --- a/crates/bevy_utils/src/lib.rs +++ b/crates/bevy_utils/src/lib.rs @@ -274,85 +274,6 @@ impl PreHashMapExt for PreHashMap Self::Hasher { - EntityHasher::default() - } -} - -/// A very fast hash that is only designed to work on generational indices -/// like `Entity`. It will panic if attempting to hash a type containing -/// non-u64 fields. -/// -/// This is heavily optimized for typical cases, where you have mostly live -/// entities, and works particularly well for contiguous indices. -/// -/// If you have an unusual case -- say all your indices are multiples of 256 -/// or most of the entities are dead generations -- then you might want also to -/// try [`AHasher`] for a slower hash computation but fewer lookup conflicts. -#[derive(Debug, Default)] -pub struct EntityHasher { - hash: u64, -} - -impl Hasher for EntityHasher { - #[inline] - fn finish(&self) -> u64 { - self.hash - } - - fn write(&mut self, _bytes: &[u8]) { - panic!("can only hash u64 using EntityHasher"); - } - - #[inline] - fn write_u64(&mut self, bits: u64) { - // SwissTable (and thus `hashbrown`) cares about two things from the hash: - // - H1: low bits (masked by `2ⁿ-1`) to pick the slot in which to store the item - // - H2: high 7 bits are used to SIMD optimize hash collision probing - // For more see - - // This hash function assumes that the entity ids are still well-distributed, - // so for H1 leaves the entity id alone in the low bits so that id locality - // will also give memory locality for things spawned together. - // For H2, take advantage of the fact that while multiplication doesn't - // spread entropy to the low bits, it's incredibly good at spreading it - // upward, which is exactly where we need it the most. - - // While this does include the generation in the output, it doesn't do so - // *usefully*. H1 won't care until you have over 3 billion entities in - // the table, and H2 won't care until something hits generation 33 million. - // Thus the comment suggesting that this is best for live entities, - // where there won't be generation conflicts where it would matter. - - // The high 32 bits of this are ⅟φ for Fibonacci hashing. That works - // particularly well for hashing for the same reason as described in - // - // It loses no information because it has a modular inverse. - // (Specifically, `0x144c_bc89_u32 * 0x9e37_79b9_u32 == 1`.) - // - // The low 32 bits make that part of the just product a pass-through. - const UPPER_PHI: u64 = 0x9e37_79b9_0000_0001; - - // This is `(MAGIC * index + generation) << 32 + index`, in a single instruction. - self.hash = bits.wrapping_mul(UPPER_PHI); - } -} - -/// A [`HashMap`] pre-configured to use [`EntityHash`] hashing. -/// Iteration order only depends on the order of insertions and deletions. -pub type EntityHashMap = hashbrown::HashMap; - -/// A [`HashSet`] pre-configured to use [`EntityHash`] hashing. -/// Iteration order only depends on the order of insertions and deletions. -pub type EntityHashSet = hashbrown::HashSet; - /// A specialized hashmap type with Key of [`TypeId`] /// Iteration order only depends on the order of insertions and deletions. pub type TypeIdMap = hashbrown::HashMap;