use core::hash::{BuildHasher, Hasher};12#[cfg(feature = "bevy_reflect")]3use bevy_reflect::{std_traits::ReflectDefault, Reflect};45/// A [`BuildHasher`] that results in a [`EntityHasher`].6#[derive(Debug, Default, Clone)]7#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Default, Clone))]8pub struct EntityHash;910impl BuildHasher for EntityHash {11type Hasher = EntityHasher;1213fn build_hasher(&self) -> Self::Hasher {14Self::Hasher::default()15}16}1718/// A very fast hash that is only designed to work on generational indices19/// like [`Entity`](super::Entity). It will panic if attempting to hash a type containing20/// non-u64 fields.21///22/// This is heavily optimized for typical cases, where you have mostly live23/// entities, and works particularly well for contiguous indices.24///25/// If you have an unusual case -- say all your indices are multiples of 25626/// or most of the entities are dead generations -- then you might want also to27/// try [`DefaultHasher`](bevy_platform::hash::DefaultHasher) for a slower hash28/// computation but fewer lookup conflicts.29#[derive(Debug, Default)]30pub struct EntityHasher {31hash: u64,32}3334impl Hasher for EntityHasher {35#[inline]36fn finish(&self) -> u64 {37self.hash38}3940fn write(&mut self, _bytes: &[u8]) {41panic!("EntityHasher can only hash u64 fields.");42}4344#[inline]45fn write_u64(&mut self, bits: u64) {46// SwissTable (and thus `hashbrown`) cares about two things from the hash:47// - H1: low bits (masked by `2ⁿ-1`) to pick the slot in which to store the item48// - H2: high 7 bits are used to SIMD optimize hash collision probing49// For more see <https://abseil.io/about/design/swisstables#metadata-layout>5051// This hash function assumes that the entity ids are still well-distributed,52// so for H1 leaves the entity id alone in the low bits so that id locality53// will also give memory locality for things spawned together.54// For H2, take advantage of the fact that while multiplication doesn't55// spread entropy to the low bits, it's incredibly good at spreading it56// upward, which is exactly where we need it the most.5758// While this does include the generation in the output, it doesn't do so59// *usefully*. H1 won't care until you have over 3 billion entities in60// the table, and H2 won't care until something hits generation 33 million.61// Thus the comment suggesting that this is best for live entities,62// where there won't be generation conflicts where it would matter.6364// The high 32 bits of this are ⅟φ for Fibonacci hashing. That works65// particularly well for hashing for the same reason as described in66// <https://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/>67// It loses no information because it has a modular inverse.68// (Specifically, `0x144c_bc89_u32 * 0x9e37_79b9_u32 == 1`.)69//70// The low 32 bits make that part of the just product a pass-through.71const UPPER_PHI: u64 = 0x9e37_79b9_0000_0001;7273// This is `(MAGIC * index + generation) << 32 + index`, in a single instruction.74self.hash = bits.wrapping_mul(UPPER_PHI);75}76}777879