Skip to main content

bevy_ecs/entity/
hash.rs

1use core::hash::{BuildHasher, Hasher};
2
3#[cfg(feature = "bevy_reflect")]
4use bevy_reflect::{std_traits::ReflectDefault, Reflect};
5
6/// 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;
10
11impl BuildHasher for EntityHash {
12    type Hasher = EntityHasher;
13
14    #[inline]
15    fn build_hasher(&self) -> Self::Hasher {
16        Self::Hasher::default()
17    }
18}
19
20/// 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}
35
36impl Hasher for EntityHasher {
37    #[inline]
38    fn finish(&self) -> u64 {
39        self.hash
40    }
41
42    fn 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    }
45
46    #[inline]
47    fn 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>
52
53        // 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.
59
60        // 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.
65
66        // 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.
73        const UPPER_PHI: u64 = 0x9e37_79b9_0000_0001;
74
75        // This is `(MAGIC * index + generation) << 32 + index`, in a single instruction.
76        self.hash = bits.wrapping_mul(UPPER_PHI);
77    }
78}