1use core::hash::{BuildHasher, Hasher};
23#[cfg(feature = "bevy_reflect")]
4use bevy_reflect::{std_traits::ReflectDefault, Reflect};
56/// A [`BuildHasher`] that results in a [`EntityHasher`].
7#[derive(#[automatically_derived]impl ::core::fmt::Debug for EntityHash {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "EntityHash")
}
}Debug, #[automatically_derived]impl ::core::default::Default for EntityHash {
#[inline]
fn default() -> Self { EntityHash {} }
}Default, #[automatically_derived]impl ::core::clone::Clone for EntityHash {
#[inline]
fn clone(&self) -> Self { EntityHash }
}Clone)]
8#[cfg_attr(feature = "bevy_reflect", derive(const _: () =
{
impl bevy_reflect::GetTypeRegistration for EntityHash where {
fn get_type_registration() -> bevy_reflect::TypeRegistration {
let mut registration =
bevy_reflect::TypeRegistration::of::<Self>();
registration.insert(<bevy_reflect::ReflectFromPtr as
bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
registration.insert(<bevy_reflect::ReflectFromReflect as
bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
registration.register_type_data_with::<ReflectDefault, Self,
_>(());
registration
}
#[inline(never)]
fn register_type_dependencies(registry:
&mut bevy_reflect::TypeRegistry) {}
}
impl bevy_reflect::Typed for EntityHash where {
#[inline(never)]
fn type_info() -> &'static bevy_reflect::TypeInfo {
static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
bevy_reflect::utility::NonGenericTypeInfoCell::new();
CELL.get_or_set(#[inline(never)] ||
{
bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[]))
})
}
}
#[allow(deprecated, reason =
"derives on a deprecated type shouldn't be considered a usage")]
impl bevy_reflect::TypePath for EntityHash where {
fn type_path() -> &'static str {
"bevy_ecs::entity::hash::EntityHash"
}
fn short_type_path() -> &'static str { "EntityHash" }
fn type_ident() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("EntityHash")
}
fn crate_name() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_ecs::entity::hash".split(':').next().unwrap())
}
fn module_path() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_ecs::entity::hash")
}
}
impl bevy_reflect::Reflect for EntityHash where {
#[inline]
fn into_any(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
self
}
#[inline]
fn as_any(&self) -> &dyn ::core::any::Any { self }
#[inline]
fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
#[inline]
fn into_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
#[inline]
fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
self
}
#[inline]
fn set(&mut self,
value:
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
->
::core::result::Result<(),
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
*self = <dyn bevy_reflect::Reflect>::take(value)?;
::core::result::Result::Ok(())
}
}
impl bevy_reflect::func::args::GetOwnership for EntityHash where {
fn ownership() -> bevy_reflect::func::args::Ownership {
bevy_reflect::func::args::Ownership::Owned
}
}
impl bevy_reflect::func::args::FromArg for EntityHash where {
type This<'from_arg> = EntityHash;
fn from_arg(arg: bevy_reflect::func::args::Arg)
->
::core::result::Result<Self::This<'_>,
bevy_reflect::func::args::ArgError> {
arg.take_owned()
}
}
impl bevy_reflect::func::IntoReturn for EntityHash where {
fn into_return<'into_return>(self)
-> bevy_reflect::func::Return<'into_return> where
Self: 'into_return {
bevy_reflect::func::Return::Owned(bevy_reflect::__macro_exports::alloc_utils::Box::new(self))
}
}
impl bevy_reflect::structs::Struct for EntityHash where {
fn field(&self, name: &str)
-> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
match name { _ => ::core::option::Option::None, }
}
fn field_mut(&mut self, name: &str)
->
::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
match name { _ => ::core::option::Option::None, }
}
fn field_at(&self, index: usize)
-> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
match index { _ => ::core::option::Option::None, }
}
fn field_at_mut(&mut self, index: usize)
->
::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
match index { _ => ::core::option::Option::None, }
}
fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
match index { _ => ::core::option::Option::None, }
}
fn index_of_name(&self, name: &str)
-> ::core::option::Option<usize> {
match name { _ => ::core::option::Option::None, }
}
fn field_len(&self) -> usize { 0usize }
fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
bevy_reflect::structs::FieldIter::new(self)
}
fn to_dynamic_struct(&self)
->
::core::result::Result<bevy_reflect::structs::DynamicStruct,
bevy_reflect::ReflectCloneError> {
let mut dynamic: bevy_reflect::structs::DynamicStruct =
::core::default::Default::default();
dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
::core::result::Result::Ok(dynamic)
}
}
impl bevy_reflect::PartialReflect for EntityHash where {
#[inline]
fn get_represented_type_info(&self)
-> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
::core::option::Option::Some(<Self as
bevy_reflect::Typed>::type_info())
}
#[inline]
fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
-> ::core::result::Result<(), bevy_reflect::ApplyError> {
if let bevy_reflect::ReflectRef::Struct(struct_value) =
bevy_reflect::PartialReflect::reflect_ref(value) {
for (name, value) in
bevy_reflect::structs::Struct::iter_fields(struct_value) {
if let ::core::option::Option::Some(v) =
bevy_reflect::structs::Struct::field_mut(self, name) {
bevy_reflect::PartialReflect::try_apply(v, value)?;
}
}
} else {
return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
to_kind: bevy_reflect::ReflectKind::Struct,
});
}
::core::result::Result::Ok(())
}
#[inline]
fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
bevy_reflect::ReflectKind::Struct
}
#[inline]
fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
bevy_reflect::ReflectRef::Struct(self)
}
#[inline]
fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
bevy_reflect::ReflectMut::Struct(self)
}
#[inline]
fn reflect_owned(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
-> bevy_reflect::ReflectOwned {
bevy_reflect::ReflectOwned::Struct(self)
}
#[inline]
fn try_into_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
::core::result::Result::Ok(self)
}
#[inline]
fn try_as_reflect(&self)
-> ::core::option::Option<&dyn bevy_reflect::Reflect> {
::core::option::Option::Some(self)
}
#[inline]
fn try_as_reflect_mut(&mut self)
-> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
::core::option::Option::Some(self)
}
#[inline]
fn into_partial_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
self
}
#[inline]
fn as_partial_reflect(&self)
-> &dyn bevy_reflect::PartialReflect {
self
}
#[inline]
fn as_partial_reflect_mut(&mut self)
-> &mut dyn bevy_reflect::PartialReflect {
self
}
fn reflect_partial_eq(&self,
value: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<bool> {
(bevy_reflect::structs::struct_partial_eq)(self, value)
}
fn reflect_partial_cmp(&self,
value: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<::core::cmp::Ordering> {
(bevy_reflect::structs::struct_partial_cmp)(self, value)
}
#[inline]
fn reflect_clone(&self)
->
::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
bevy_reflect::ReflectCloneError> {
::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(::core::clone::Clone::clone(self)))
}
}
impl bevy_reflect::FromReflect for EntityHash where {
fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<Self> {
if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
bevy_reflect::PartialReflect::reflect_ref(reflect) {
let mut __this =
<Self as ::core::default::Default>::default();
::core::option::Option::Some(__this)
} else { ::core::option::Option::None }
}
}
};Reflect), reflect(Default, Clone))]
9pub struct EntityHash;
1011impl BuildHasherfor EntityHash {
12type Hasher = EntityHasher;
1314#[inline]
15fn build_hasher(&self) -> Self::Hasher {
16Self::Hasher::default()
17 }
18}
1920/// A very fast hash that is only designed to work on generational indices
21/// like [`Entity`](super::Entity). It will panic if attempting to hash a type containing
22/// non-u64 fields.
23///
24/// This is heavily optimized for typical cases, where you have mostly live
25/// entities, and works particularly well for contiguous indices.
26///
27/// If you have an unusual case -- say all your indices are multiples of 256
28/// or most of the entities are dead generations -- then you might want also to
29/// try [`DefaultHasher`](bevy_platform::hash::DefaultHasher) for a slower hash
30/// computation but fewer lookup conflicts.
31#[derive(#[automatically_derived]impl ::core::fmt::Debug for EntityHasher {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "EntityHasher",
"hash", &&self.hash)
}
}Debug, #[automatically_derived]impl ::core::default::Default for EntityHasher {
#[inline]
fn default() -> Self {
EntityHasher { hash: ::core::default::Default::default() }
}
}Default)]
32pub struct EntityHasher {
33 hash: u64,
34}
3536impl Hasherfor EntityHasher {
37#[inline]
38fn finish(&self) -> u64 {
39self.hash
40 }
4142fn write(&mut self, _bytes: &[u8]) {
43{
::core::panicking::panic_fmt(format_args!("EntityHasher can only hash u64 fields."));
};panic!("EntityHasher can only hash u64 fields.");
44 }
4546#[inline]
47fn write_u64(&mut self, bits: u64) {
48// SwissTable (and thus `hashbrown`) cares about two things from the hash:
49 // - H1: low bits (masked by `2ⁿ-1`) to pick the slot in which to store the item
50 // - H2: high 7 bits are used to SIMD optimize hash collision probing
51 // For more see <https://abseil.io/about/design/swisstables#metadata-layout>
5253 // This hash function assumes that the entity ids are still well-distributed,
54 // so for H1 leaves the entity id alone in the low bits so that id locality
55 // will also give memory locality for things spawned together.
56 // For H2, take advantage of the fact that while multiplication doesn't
57 // spread entropy to the low bits, it's incredibly good at spreading it
58 // upward, which is exactly where we need it the most.
5960 // While this does include the generation in the output, it doesn't do so
61 // *usefully*. H1 won't care until you have over 3 billion entities in
62 // the table, and H2 won't care until something hits generation 33 million.
63 // Thus the comment suggesting that this is best for live entities,
64 // where there won't be generation conflicts where it would matter.
6566 // The high 32 bits of this are ⅟φ for Fibonacci hashing. That works
67 // particularly well for hashing for the same reason as described in
68 // <https://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/>
69 // It loses no information because it has a modular inverse.
70 // (Specifically, `0x144c_bc89_u32 * 0x9e37_79b9_u32 == 1`.)
71 //
72 // The low 32 bits make that part of the just product a pass-through.
73const UPPER_PHI: u64 = 0x9e37_79b9_0000_0001;
7475// This is `(MAGIC * index + generation) << 32 + index`, in a single instruction.
76self.hash = bits.wrapping_mul(UPPER_PHI);
77 }
78}