RuntimeBlockMapping: share states CompoundTags if they are the same

this allows saving about 4 MB of memory, because there are many blocks which have identical states, although they have different IDs.

this relies on a potentially risky assumption that the tags in knownStates won't be modified. If they are modified, the changes will influence all blockstates which share the tag.
However, I don't expect this to happen, and the 4 MB memory saving is substantial enough to be worth the risk.
This commit is contained in:
Dylan K. Taylor 2023-05-04 23:21:54 +01:00
parent 092d130c96
commit 633e77a34c
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D

View File

@ -27,10 +27,12 @@ use pocketmine\block\Block;
use pocketmine\block\BlockLegacyIds;
use pocketmine\data\bedrock\BedrockDataFiles;
use pocketmine\data\bedrock\LegacyBlockIdToStringIdMap;
use pocketmine\nbt\LittleEndianNbtSerializer;
use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\nbt\TreeRoot;
use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer;
use pocketmine\utils\BinaryStream;
use pocketmine\utils\Filesystem;
@ -72,7 +74,7 @@ final class RuntimeBlockMapping{
$key = $keyIndex[$key] ??= $key;
if($value instanceof CompoundTag){
$value = self::deduplicateCompound($value, $keyIndex, $valueIndex);
$value = $valueIndex[$value->getType()][(new LittleEndianNbtSerializer())->write(new TreeRoot($value))] ??= self::deduplicateCompound($value, $keyIndex, $valueIndex);
}elseif($value instanceof ByteTag || $value instanceof IntTag || $value instanceof StringTag){
$value = $valueIndex[$value->getType()][$value->getValue()] ??= $value;
}