From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 24 Oct 2024 08:20:45 -0700 Subject: [PATCH] Moonrise: optimise palette reads Original license: GPLv3 Original project: - https://github.com/Tuinity/Moonrise - https://github.com/PaperMC/Paper This patch is based on the following mixin: "ca/spottedleaf/moonrise/mixin/fast_palette/CrudeIncrementalIntIdentityHashBiMapMixin.java" "ca/spottedleaf/moonrise/mixin/fast_palette/HashMapPaletteMixin.java" "ca/spottedleaf/moonrise/mixin/fast_palette/LinearPaletteMixin.java" "ca/spottedleaf/moonrise/mixin/fast_palette/PaletteMixin.java" "ca/spottedleaf/moonrise/mixin/fast_palette/PalettedContainerMixin.java" "ca/spottedleaf/moonrise/mixin/fast_palette/SingleValuePaletteMixin.java" Replace palette read with optimised version diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java new file mode 100644 index 0000000000000000000000000000000000000000..4a7abd239a9c59aa98947e7993962d75e9051902 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java @@ -0,0 +1,9 @@ +package ca.spottedleaf.moonrise.patches.fast_palette; + +public interface FastPalette { + + public default T[] moonrise$getRawPalette(final FastPaletteData src) { + return null; + } + +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java new file mode 100644 index 0000000000000000000000000000000000000000..4503f3495846a7d7ed082b9e24636044e4fbccd1 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java @@ -0,0 +1,9 @@ +package ca.spottedleaf.moonrise.patches.fast_palette; + +public interface FastPaletteData { + + public T[] moonrise$getPalette(); + + public void moonrise$setPalette(final T[] palette); + +} diff --git a/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java b/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java index 61dee55417bc802e25b9ba2f271d32d8c12844a9..5794ce906fd562f84f09f45ebb6d742dbc3ff3df 100644 --- a/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java +++ b/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java @@ -7,7 +7,7 @@ import java.util.Iterator; import javax.annotation.Nullable; import net.minecraft.core.IdMap; -public class CrudeIncrementalIntIdentityHashBiMap implements IdMap { +public class CrudeIncrementalIntIdentityHashBiMap implements IdMap, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Moonrise - optimise palette reads private static final int NOT_FOUND = -1; private static final Object EMPTY_SLOT = null; private static final float LOADFACTOR = 0.8F; @@ -17,6 +17,16 @@ public class CrudeIncrementalIntIdentityHashBiMap implements IdMap { private int nextId; private int size; + // Moonrise start - optimise palette reads + private ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData reference; + + @Override + public final K[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData src) { + this.reference = src; + return this.byId; + } + // Moonrise end - optimise palette reads + private CrudeIncrementalIntIdentityHashBiMap(int size) { this.keys = (K[])(new Object[size]); this.values = new int[size]; @@ -88,6 +98,12 @@ public class CrudeIncrementalIntIdentityHashBiMap implements IdMap { this.byId = crudeIncrementalIntIdentityHashBiMap.byId; this.nextId = crudeIncrementalIntIdentityHashBiMap.nextId; this.size = crudeIncrementalIntIdentityHashBiMap.size; + // Moonrise start - optimise palette reads + final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData ref = this.reference; + if (ref != null) { + ref.moonrise$setPalette(this.byId); + } + // Moonrise end - optimise palette reads } public void addMapping(K value, int id) { diff --git a/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java b/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java index c5e1040c239874dcf20b79472bf690ee7f0a9e5f..02b97e22fd9a122cc8f1628ef3205e87145a89fb 100644 --- a/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java +++ b/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java @@ -8,12 +8,19 @@ import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.VarInt; import net.minecraft.util.CrudeIncrementalIntIdentityHashBiMap; -public class HashMapPalette implements Palette { +public class HashMapPalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Moonrise - optimise palette reads private final IdMap registry; private final CrudeIncrementalIntIdentityHashBiMap values; private final PaletteResize resizeHandler; private final int bits; + // Moonrise start - optimise palette reads + @Override + public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { + return ((ca.spottedleaf.moonrise.patches.fast_palette.FastPalette) this.values).moonrise$getRawPalette(container); + } + // Moonrise end - optimise palette reads + public HashMapPalette(IdMap idList, int bits, PaletteResize listener, List entries) { this(idList, bits, listener); entries.forEach(this.values::add); diff --git a/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java b/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java index f4c3f2a49b8d023b8ef67529eba30cf31467d8bf..e070b9d805b86c0cf08804d1b14e580ab9986d7d 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java +++ b/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java @@ -7,13 +7,20 @@ import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.VarInt; import org.apache.commons.lang3.Validate; -public class LinearPalette implements Palette { +public class LinearPalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Moonrise - optimise palette reads private final IdMap registry; private final T[] values; private final PaletteResize resizeHandler; private final int bits; private int size; + // Moonrise start - optimise palette reads + @Override + public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { + return this.values; + } + // Moonrise end - optimise palette reads + private LinearPalette(IdMap idList, int bits, PaletteResize listener, List list) { this.registry = idList; this.values = (T[])(new Object[1 << bits]); diff --git a/src/main/java/net/minecraft/world/level/chunk/Palette.java b/src/main/java/net/minecraft/world/level/chunk/Palette.java index e379f39cc6e03723a5323d8392b4c10bfde65115..91b16f0df26daa45f5a30eb36bdc9adac794779a 100644 --- a/src/main/java/net/minecraft/world/level/chunk/Palette.java +++ b/src/main/java/net/minecraft/world/level/chunk/Palette.java @@ -5,7 +5,7 @@ import java.util.function.Predicate; import net.minecraft.core.IdMap; import net.minecraft.network.FriendlyByteBuf; -public interface Palette { +public interface Palette extends ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Moonrise - optimise palette reads int idFor(T object); boolean maybeHas(Predicate predicate); diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java index 15f3f68dfa933432f163218ccc9f66b9baef0d9d..b14d0f8247b092ce3b655971397e301ed7b2a21e 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java @@ -57,6 +57,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer // this.threadingDetector.checkAndUnlock(); // Paper - disable this } + // Moonrise start - optimise palette reads + private void updateData(final PalettedContainer.Data data) { + if (data != null) { + ((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData) (Object) data).moonrise$setPalette( + ((ca.spottedleaf.moonrise.patches.fast_palette.FastPalette) data.palette).moonrise$getRawPalette((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData) (Object) data) + ); + } + } + + private T readPaletteSlow(final PalettedContainer.Data data, final int paletteIdx) { + return data.palette.valueFor(paletteIdx); + } + + private T readPalette(final PalettedContainer.Data data, final int paletteIdx) { + final T[] palette = ((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData) (Object) data).moonrise$getPalette(); + if (palette == null) { + return this.readPaletteSlow(data, paletteIdx); + } + + final T ret = palette[paletteIdx]; + if (ret == null) { + throw new IllegalArgumentException("Palette index out of bounds"); + } + return ret; + } + // Moonrise end - optimise palette reads + // Paper start - Anti-Xray - Add preset values @Deprecated @io.papermc.paper.annotation.DoNotUse public static Codec> codecRW(IdMap idList, Codec entryCodec, PalettedContainer.Strategy paletteProvider, T defaultValue) { return PalettedContainer.codecRW(idList, entryCodec, paletteProvider, defaultValue, null); } public static Codec> codecRW(IdMap idList, Codec entryCodec, PalettedContainer.Strategy paletteProvider, T defaultValue, T @org.jetbrains.annotations.Nullable [] presetValues) { @@ -129,6 +156,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } } // Paper end + this.updateData(this.data); // Moonrise - optimise palette reads } // Paper start - Anti-Xray - Add preset values @@ -138,6 +166,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer this.registry = idList; this.strategy = paletteProvider; this.data = data; + this.updateData(this.data); // Moonrise - optimise palette reads } // Paper start - Anti-Xray - Add preset values @@ -149,6 +178,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer this.registry = idList; this.data = this.createOrReuseData(null, 0); this.data.palette.idFor(object); + this.updateData(this.data); // Moonrise - optimise palette reads } private PalettedContainer.Data createOrReuseData(@Nullable PalettedContainer.Data previousData, int bits) { @@ -175,6 +205,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer data2.copyFrom(data.palette, data.storage); this.data = data2; this.addPresetValues(); + this.updateData(this.data); // Moonrise - optimise palette reads return object == null ? -1 : data2.palette.idFor(object); // Paper end } @@ -207,9 +238,12 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } private synchronized T getAndSet(int index, T value) { // Paper - synchronize - int i = this.data.palette.idFor(value); - int j = this.data.storage.getAndSet(index, i); - return this.data.palette.valueFor(j); + // Moonrise start - optimise palette reads + final int paletteIdx = this.data.palette.idFor(value); + final PalettedContainer.Data data = this.data; + final int prev = data.storage.getAndSet(index, paletteIdx); + return this.readPalette(data, prev); + // Moonrise end - optimise palette reads } public void set(int x, int y, int z, T value) { @@ -233,8 +267,10 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } public T get(int index) { // Paper - public - PalettedContainer.Data data = this.data; - return data.palette.valueFor(data.storage.get(index)); + // Moonrise start - optimise palette reads + final PalettedContainer.Data data = this.data; + return this.readPalette(data, data.storage.get(index)); + // Moonrise end - optimise palette reads } @Override @@ -255,6 +291,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer buf.readLongArray(data.storage.getRaw()); this.data = data; this.addPresetValues(); // Paper - Anti-Xray - Add preset values (inefficient, but this isn't used by the server) + this.updateData(this.data); // Moonrise - optimise palette reads } finally { this.release(); } @@ -450,7 +487,44 @@ public class PalettedContainer implements PaletteResize, PalettedContainer void accept(T object, int count); } - static record Data(PalettedContainer.Configuration configuration, BitStorage storage, Palette palette) { + // Moonrise start - optimise palette reads + public static final class Data implements ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData { + + private final PalettedContainer.Configuration configuration; + private final BitStorage storage; + private final Palette palette; + + private T[] moonrise$palette; + + public Data(final PalettedContainer.Configuration configuration, final BitStorage storage, final Palette palette) { + this.configuration = configuration; + this.storage = storage; + this.palette = palette; + } + + public PalettedContainer.Configuration configuration() { + return this.configuration; + } + + public BitStorage storage() { + return this.storage; + } + + public Palette palette() { + return this.palette; + } + + @Override + public final T[] moonrise$getPalette() { + return this.moonrise$palette; + } + + @Override + public final void moonrise$setPalette(final T[] palette) { + this.moonrise$palette = palette; + } + + // Moonrise end - optimise palette reads public void copyFrom(Palette palette, BitStorage storage) { for (int i = 0; i < storage.getSize(); i++) { T object = palette.valueFor(storage.get(i)); diff --git a/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java b/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java index 24b608cfcd6f39db02e682e5d8162dc4ad9fd6d6..868ebabdcb76f4c61c9fb01e8cc75ab77845f29c 100644 --- a/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java +++ b/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java @@ -8,12 +8,24 @@ import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.VarInt; import org.apache.commons.lang3.Validate; -public class SingleValuePalette implements Palette { +public class SingleValuePalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Moonrise - optimise palette reads private final IdMap registry; @Nullable private T value; private final PaletteResize resizeHandler; + // Moonrise start - optimise palette reads + private T[] rawPalette; + + @Override + public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { + if (this.rawPalette != null) { + return this.rawPalette; + } + return this.rawPalette = (T[]) new Object[]{this.value}; + } + // Moonrise end - optimise palette reads + public SingleValuePalette(IdMap idList, PaletteResize listener, List entries) { this.registry = idList; this.resizeHandler = listener; @@ -33,6 +45,11 @@ public class SingleValuePalette implements Palette { return this.resizeHandler.onResize(1, object); } else { this.value = object; + // Moonrise start - optimise palette reads + if (this.rawPalette != null) { + this.rawPalette[0] = object; + } + // Moonrise end - optimise palette reads return 0; } } @@ -58,6 +75,11 @@ public class SingleValuePalette implements Palette { @Override public void read(FriendlyByteBuf buf) { this.value = this.registry.byIdOrThrow(buf.readVarInt()); + // Moonrise start - optimise palette reads + if (this.rawPalette != null) { + this.rawPalette[0] = this.value; + } + // Moonrise end - optimise palette reads } @Override