|
| 1 | +package org.embeddedt.modernfix.common.mixin.perf.compact_mojang_registries; |
| 2 | + |
| 3 | +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; |
| 4 | +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; |
| 5 | +import net.minecraft.nbt.CompoundTag; |
| 6 | +import net.minecraft.nbt.Tag; |
| 7 | +import net.minecraft.util.datafix.fixes.BlockStateData; |
| 8 | +import org.spongepowered.asm.mixin.Mixin; |
| 9 | +import org.spongepowered.asm.mixin.Unique; |
| 10 | +import org.spongepowered.asm.mixin.injection.At; |
| 11 | +import org.spongepowered.asm.mixin.injection.Inject; |
| 12 | +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; |
| 13 | + |
| 14 | +import java.util.Map; |
| 15 | + |
| 16 | +@Mixin(value = BlockStateData.class, priority = 2000) |
| 17 | +public class BlockStateDataMixin { |
| 18 | + @Unique |
| 19 | + private static ObjectOpenHashSet<Tag> TAG_INTERNER; |
| 20 | + |
| 21 | + /** |
| 22 | + * @author embeddedt |
| 23 | + * @reason Reduce memory use of these constant CompoundTags via aggressive interning. |
| 24 | + */ |
| 25 | + @ModifyExpressionValue(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/nbt/TagParser;parseTag(Ljava/lang/String;)Lnet/minecraft/nbt/CompoundTag;")) |
| 26 | + private static CompoundTag compactTag(CompoundTag tag) { |
| 27 | + if (TAG_INTERNER == null) { |
| 28 | + TAG_INTERNER = new ObjectOpenHashSet<>(); |
| 29 | + } |
| 30 | + Map.Entry<String, Tag>[] entries = new Map.Entry[tag.size()]; |
| 31 | + int i = 0; |
| 32 | + for (var key : tag.getAllKeys()) { |
| 33 | + Tag t = tag.get(key); |
| 34 | + if (t instanceof CompoundTag ct) { |
| 35 | + t = compactTag(ct); |
| 36 | + } |
| 37 | + t = TAG_INTERNER.addOrGet(t); |
| 38 | + entries[i++] = Map.entry(key, t); |
| 39 | + } |
| 40 | + return new CompoundTag(Map.ofEntries(entries)); |
| 41 | + } |
| 42 | + |
| 43 | + @Inject(method = "<clinit>", at = @At("RETURN")) |
| 44 | + private static void clearInterner(CallbackInfo ci) { |
| 45 | + if (TAG_INTERNER != null) { |
| 46 | + TAG_INTERNER.clear(); |
| 47 | + TAG_INTERNER.trim(); |
| 48 | + } |
| 49 | + } |
| 50 | +} |
0 commit comments