From ffe3556be1c8c20218190da184510518694f3234 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 25 May 2023 16:35:45 +0100 Subject: [PATCH] Block: XOR state data with type ID, improve hash distribution since most blocks have no state data, their lower 8 bits of state data were all zero. This makes state IDs a bit more distributed for minimal cost. I considered flipping these around and using type ID in the lower bits directly, but this worsened distribution for walls. In the worst case, largest number of collisions drops from 11 to 5 with this change, and the number of states with unique hash keys increased from 3518 to 4461 (out of 7638). This is still a long way from perfect, but it's a decent improvement, improving the overall load factor from 1.6 to 1.3. related to #5604 --- src/block/Block.php | 3 ++- src/block/RuntimeBlockStateRegistry.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index bc76bf952..3ce2dc188 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -140,7 +140,8 @@ class Block{ * {@link RuntimeBlockStateRegistry::fromStateId()}. */ public function getStateId() : int{ - return ($this->getTypeId() << self::INTERNAL_STATE_DATA_BITS) | $this->encodeFullState(); + $typeId = $this->getTypeId(); + return ($typeId << self::INTERNAL_STATE_DATA_BITS) | ($this->encodeFullState() ^ ($typeId & self::INTERNAL_STATE_DATA_MASK)); } /** diff --git a/src/block/RuntimeBlockStateRegistry.php b/src/block/RuntimeBlockStateRegistry.php index e524fb262..78be658bc 100644 --- a/src/block/RuntimeBlockStateRegistry.php +++ b/src/block/RuntimeBlockStateRegistry.php @@ -123,7 +123,7 @@ class RuntimeBlockStateRegistry{ $block = clone $this->fullList[$stateId]; }else{ $typeId = $stateId >> Block::INTERNAL_STATE_DATA_BITS; - $stateData = $stateId & Block::INTERNAL_STATE_DATA_MASK; + $stateData = ($stateId ^ $typeId) & Block::INTERNAL_STATE_DATA_MASK; $block = new UnknownBlock(new BID($typeId), new BlockTypeInfo(BreakInfo::instant()), $stateData); }