Skip to content

Commit 65d7b88

Browse files
committed
More comments on the approach
1 parent 5c48fd7 commit 65d7b88

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

crates/bevy_utils/src/lib.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,20 @@ impl Hasher for EntityHasher {
285285

286286
#[inline]
287287
fn write_u64(&mut self, i: u64) {
288+
// We ignore the generation entirely. It's always functionally correct
289+
// to omit things when hashing, so long as it's consistent, just a perf
290+
// trade-off. This hasher is designed for "normal" cases, where nearly
291+
// everything in the table is a live entity, meaning there are few
292+
// generation conflicts. And thus it's overall faster to just ignore
293+
// the generation during hashing, leaving it to the `Entity::eq` to
294+
// confirm the generation matches -- just like `Entity::eq` checks that
295+
// the index is actually the right one, since there's always the chance
296+
// of a conflict in the index despite a good hash function.
297+
//
298+
// This masking actually ends up with negative cost after optimization,
299+
// since it saves needing to do the shift-and-or between the fields.
300+
let index = i & 0xFFFF_FFFF;
301+
288302
// SwissTable (and thus `hashbrown`) cares about two things from the hash:
289303
// - H1: low bits (masked by `2ⁿ-1`) to pick the slot in which to store the item
290304
// - H2: high 7 bits are used to SIMD optimize hash collision probing
@@ -302,11 +316,10 @@ impl Hasher for EntityHasher {
302316
// <https://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/>
303317
// It loses no information because it has a modular inverse.
304318
// (Specifically, `0x144c_bc89_u32 * 0x9e37_79b9_u32 == 1`.)
319+
//
305320
// The low 32 bits are just 1, to leave the entity id there unchanged.
306321
const UPPER_PHI: u64 = 0x9e37_79b9_0000_0001;
307-
// This bit-masking is free, as the optimizer can just not load the generation.
308-
let id = i & 0xFFFF_FFFF;
309-
self.hash = id.wrapping_mul(UPPER_PHI);
322+
self.hash = index.wrapping_mul(UPPER_PHI);
310323
}
311324

312325
#[inline]

0 commit comments

Comments
 (0)