mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-04 00:55:14 +00:00
BlockStateDictionary: reduce memory footprint by 5 MB by deduplicating blockstate NBT keys and values
This commit is contained in:
@ -25,6 +25,10 @@ namespace pocketmine\network\mcpe\convert;
|
|||||||
|
|
||||||
use pocketmine\data\bedrock\block\BlockStateData;
|
use pocketmine\data\bedrock\block\BlockStateData;
|
||||||
use pocketmine\nbt\NbtDataException;
|
use pocketmine\nbt\NbtDataException;
|
||||||
|
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\nbt\TreeRoot;
|
||||||
use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer;
|
use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer;
|
||||||
use function array_map;
|
use function array_map;
|
||||||
@ -108,6 +112,33 @@ final class BlockStateDictionary{
|
|||||||
*/
|
*/
|
||||||
public function getStates() : array{ return $this->states; }
|
public function getStates() : array{ return $this->states; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $keyIndex
|
||||||
|
* @param (ByteTag|StringTag|IntTag)[][] $valueIndex
|
||||||
|
* @phpstan-param array<string, string> $keyIndex
|
||||||
|
* @phpstan-param array<int, array<int|string, ByteTag|IntTag|StringTag>> $valueIndex
|
||||||
|
*/
|
||||||
|
private static function deduplicateCompound(CompoundTag $tag, array &$keyIndex, array &$valueIndex) : CompoundTag{
|
||||||
|
if($tag->count() === 0){
|
||||||
|
return $tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
$newTag = CompoundTag::create();
|
||||||
|
foreach($tag as $key => $value){
|
||||||
|
$key = $keyIndex[$key] ??= $key;
|
||||||
|
|
||||||
|
if($value instanceof CompoundTag){
|
||||||
|
$value = self::deduplicateCompound($value, $keyIndex, $valueIndex);
|
||||||
|
}elseif($value instanceof ByteTag || $value instanceof IntTag || $value instanceof StringTag){
|
||||||
|
$value = $valueIndex[$value->getType()][$value->getValue()] ??= $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$newTag->setTag($key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $newTag;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BlockStateData[]
|
* @return BlockStateData[]
|
||||||
* @phpstan-return list<BlockStateData>
|
* @phpstan-return list<BlockStateData>
|
||||||
@ -115,8 +146,13 @@ final class BlockStateDictionary{
|
|||||||
* @throws NbtDataException
|
* @throws NbtDataException
|
||||||
*/
|
*/
|
||||||
public static function loadPaletteFromString(string $blockPaletteContents) : array{
|
public static function loadPaletteFromString(string $blockPaletteContents) : array{
|
||||||
|
$keyIndex = [];
|
||||||
|
$valueIndex = [];
|
||||||
|
|
||||||
return array_map(
|
return array_map(
|
||||||
fn(TreeRoot $root) => BlockStateData::fromNbt($root->mustGetCompoundTag()),
|
function(TreeRoot $root) use (&$keyIndex, &$valueIndex) : BlockStateData{
|
||||||
|
return BlockStateData::fromNbt(self::deduplicateCompound($root->mustGetCompoundTag(), $keyIndex, $valueIndex));
|
||||||
|
},
|
||||||
(new NetworkNbtSerializer())->readMultiple($blockPaletteContents)
|
(new NetworkNbtSerializer())->readMultiple($blockPaletteContents)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user