From 1176cc98e3a700abe91979375c240313220d9d20 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 26 Dec 2025 14:02:15 -0500 Subject: [PATCH] Compact NBT used for Flattening world upgrades --- .../BlockStateDataMixin.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/BlockStateDataMixin.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/BlockStateDataMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/BlockStateDataMixin.java new file mode 100644 index 00000000..eb85f08c --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/BlockStateDataMixin.java @@ -0,0 +1,50 @@ +package org.embeddedt.modernfix.common.mixin.perf.compact_mojang_registries; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.util.datafix.fixes.BlockStateData; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.Map; + +@Mixin(value = BlockStateData.class, priority = 2000) +public class BlockStateDataMixin { + @Unique + private static ObjectOpenHashSet TAG_INTERNER; + + /** + * @author embeddedt + * @reason Reduce memory use of these constant CompoundTags via aggressive interning. + */ + @ModifyExpressionValue(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/nbt/TagParser;parseTag(Ljava/lang/String;)Lnet/minecraft/nbt/CompoundTag;")) + private static CompoundTag compactTag(CompoundTag tag) { + if (TAG_INTERNER == null) { + TAG_INTERNER = new ObjectOpenHashSet<>(); + } + Map.Entry[] entries = new Map.Entry[tag.size()]; + int i = 0; + for (var key : tag.getAllKeys()) { + Tag t = tag.get(key); + if (t instanceof CompoundTag ct) { + t = compactTag(ct); + } + t = TAG_INTERNER.addOrGet(t); + entries[i++] = Map.entry(key, t); + } + return new CompoundTag(Map.ofEntries(entries)); + } + + @Inject(method = "", at = @At("RETURN")) + private static void clearInterner(CallbackInfo ci) { + if (TAG_INTERNER != null) { + TAG_INTERNER.clear(); + TAG_INTERNER.trim(); + } + } +}