From 64cbc78484655d597c9c51e59cf0ca46a1603cc4 Mon Sep 17 00:00:00 2001 From: NanaChiyo0721 Date: Mon, 20 Jul 2026 20:48:14 +0800 Subject: [PATCH] Leaf: Lithium faster hash palette This is a part of Leaf(https://github.com/Winds-Studio/Leaf/blob/8293ae2d0ada9df24e944f755b50e93208c1496d/leaf-server/minecraft-patches/features/0281-Lithium-faster-hash-palette.patch) Original proj license: https://github.com/Winds-Studio/Leaf/blob/8293ae2d0ada9df24e944f755b50e93208c1496d/LICENSE.md This patch is based on the following mixins: * "net/caffeinemc/mods/lithium/mixin/chunk/palette/StrategyMixin.java" By: 2No2Name <2No2Name@web.de> As part of: Lithium (https://github.com/CaffeineMC/lithium) Licensed under: LGPL-3.0-only (https://www.gnu.org/licenses/lgpl-3.0.html) --- ...058-Leaf-Lithium-faster-hash-palette.patch | 83 +++++++ ...cket-limit-Shiroha-Option-to-full-d.patch} | 0 ...ves-Configurable-collision-behavior.patch} | 0 ...061-Leaves-Optimized-dragon-respawn.patch} | 0 ...le-Variable-entity-wake-up-duration.patch} | 0 ...ttributes-with-optimized-collection.patch} | 0 ...kip-entity-move-if-movement-is-zero.patch} | 0 ...5-Gale-Store-mob-counts-in-an-array.patch} | 0 ...imize-random-calls-in-chunk-ticking.patch} | 0 ...uce-enderman-teleport-chunk-lookups.patch} | 0 ...> 0068-Gale-Cache-ShapePairKey-hash.patch} | 0 ...n-check-has-physics-before-same-veh.patch} | 0 ...ible-planar-movement-multiplication.patch} | 0 ...-Gale-Optimize-matching-item-checks.patch} | 0 ...a-and-Optional-allocation-in-Entity.patch} | 0 ... 0073-Gale-Reduce-array-allocations.patch} | 0 ...074-Some-optimizations-from-krypton.patch} | 0 ...h => 0075-Frustum-filtering-tracker.patch} | 0 .../world/chunk/LithiumHashPalette.java | 224 ++++++++++++++++++ 19 files changed, 307 insertions(+) create mode 100644 shiroha-server/minecraft-patches/features/0058-Leaf-Lithium-faster-hash-palette.patch rename shiroha-server/minecraft-patches/features/{0058-Leaves-Disable-packet-limit-Shiroha-Option-to-full-d.patch => 0059-Leaves-Disable-packet-limit-Shiroha-Option-to-full-d.patch} (100%) rename shiroha-server/minecraft-patches/features/{0059-Leaves-Configurable-collision-behavior.patch => 0060-Leaves-Configurable-collision-behavior.patch} (100%) rename shiroha-server/minecraft-patches/features/{0060-Leaves-Optimized-dragon-respawn.patch => 0061-Leaves-Optimized-dragon-respawn.patch} (100%) rename shiroha-server/minecraft-patches/features/{0061-Gale-Variable-entity-wake-up-duration.patch => 0062-Gale-Variable-entity-wake-up-duration.patch} (100%) rename shiroha-server/minecraft-patches/features/{0062-Gale-Replace-AI-attributes-with-optimized-collection.patch => 0063-Gale-Replace-AI-attributes-with-optimized-collection.patch} (100%) rename shiroha-server/minecraft-patches/features/{0063-Gale-Skip-entity-move-if-movement-is-zero.patch => 0064-Gale-Skip-entity-move-if-movement-is-zero.patch} (100%) rename shiroha-server/minecraft-patches/features/{0064-Gale-Store-mob-counts-in-an-array.patch => 0065-Gale-Store-mob-counts-in-an-array.patch} (100%) rename shiroha-server/minecraft-patches/features/{0065-Gale-Optimize-random-calls-in-chunk-ticking.patch => 0066-Gale-Optimize-random-calls-in-chunk-ticking.patch} (100%) rename shiroha-server/minecraft-patches/features/{0066-Gale-Reduce-enderman-teleport-chunk-lookups.patch => 0067-Gale-Reduce-enderman-teleport-chunk-lookups.patch} (100%) rename shiroha-server/minecraft-patches/features/{0067-Gale-Cache-ShapePairKey-hash.patch => 0068-Gale-Cache-ShapePairKey-hash.patch} (100%) rename shiroha-server/minecraft-patches/features/{0068-Gale-For-collision-check-has-physics-before-same-veh.patch => 0069-Gale-For-collision-check-has-physics-before-same-veh.patch} (100%) rename shiroha-server/minecraft-patches/features/{0069-Gale-Skip-negligible-planar-movement-multiplication.patch => 0070-Gale-Skip-negligible-planar-movement-multiplication.patch} (100%) rename shiroha-server/minecraft-patches/features/{0070-Gale-Optimize-matching-item-checks.patch => 0071-Gale-Optimize-matching-item-checks.patch} (100%) rename shiroha-server/minecraft-patches/features/{0071-Gale-Reduce-lambda-and-Optional-allocation-in-Entity.patch => 0072-Gale-Reduce-lambda-and-Optional-allocation-in-Entity.patch} (100%) rename shiroha-server/minecraft-patches/features/{0072-Gale-Reduce-array-allocations.patch => 0073-Gale-Reduce-array-allocations.patch} (100%) rename shiroha-server/minecraft-patches/features/{0073-Some-optimizations-from-krypton.patch => 0074-Some-optimizations-from-krypton.patch} (100%) rename shiroha-server/minecraft-patches/features/{0074-Frustum-filtering-tracker.patch => 0075-Frustum-filtering-tracker.patch} (100%) create mode 100644 shiroha-server/src/main/java/net/caffeinemc/mods/lithium/common/world/chunk/LithiumHashPalette.java diff --git a/shiroha-server/minecraft-patches/features/0058-Leaf-Lithium-faster-hash-palette.patch b/shiroha-server/minecraft-patches/features/0058-Leaf-Lithium-faster-hash-palette.patch new file mode 100644 index 0000000..d2fe244 --- /dev/null +++ b/shiroha-server/minecraft-patches/features/0058-Leaf-Lithium-faster-hash-palette.patch @@ -0,0 +1,83 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NanaChiyo0721 +Date: Mon, 20 Jul 2026 20:41:53 +0800 +Subject: [PATCH] Leaf: Lithium: faster hash palette + +This is a part of Leaf(https://github.com/Winds-Studio/Leaf/blob/8293ae2d0ada9df24e944f755b50e93208c1496d/leaf-server/minecraft-patches/features/0281-Lithium-faster-hash-palette.patch) + +Original proj license: https://github.com/Winds-Studio/Leaf/blob/8293ae2d0ada9df24e944f755b50e93208c1496d/LICENSE.md + +This patch is based on the following mixins: +* "net/caffeinemc/mods/lithium/mixin/chunk/palette/StrategyMixin.java" +By: 2No2Name <2No2Name@web.de> +As part of: Lithium (https://github.com/CaffeineMC/lithium) +Licensed under: LGPL-3.0-only (https://www.gnu.org/licenses/lgpl-3.0.html) + +diff --git a/net/minecraft/world/level/chunk/HashMapPalette.java b/net/minecraft/world/level/chunk/HashMapPalette.java +index 3ee35885ea1f997bb5a36dd8d5f83b168883ba61..2cee753e9927f04d8c77e179f34442ef8469de76 100644 +--- a/net/minecraft/world/level/chunk/HashMapPalette.java ++++ b/net/minecraft/world/level/chunk/HashMapPalette.java +@@ -14,7 +14,7 @@ public class HashMapPalette implements Palette, ca.spottedleaf.moonrise.pa + + // Paper start - optimise palette reads + @Override +- public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { ++ public T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { // Leaf - Lithium - faster hash palette - public final -> public + return ((ca.spottedleaf.moonrise.patches.fast_palette.FastPalette)this.values).moonrise$getRawPalette(container); + } + // Paper end - optimise palette reads +@@ -28,6 +28,14 @@ public class HashMapPalette implements Palette, ca.spottedleaf.moonrise.pa + this(bits, CrudeIncrementalIntIdentityHashBiMap.create((1 << bits) + 1)); // Paper - Perf: Avoid unnecessary resize operation in CrudeIncrementalIntIdentityHashBiMap + } + ++ // Leaf start - Lithium - faster hash palette ++ protected HashMapPalette(int bits, boolean dummy) { ++ this.bits = bits; ++ //noinspection DataFlowIssue ++ this.values = dummy ? null : CrudeIncrementalIntIdentityHashBiMap.create((1 << bits) + 1); ++ } ++ // Leaf end - Lithium - faster hash palette ++ + private HashMapPalette(final int bits, final CrudeIncrementalIntIdentityHashBiMap values) { + this.bits = bits; + this.values = values; +diff --git a/net/minecraft/world/level/chunk/Strategy.java b/net/minecraft/world/level/chunk/Strategy.java +index 958be147cd940ac430576ca5b4ada70fa5d051e3..d88f93a581c7087540872e8ad0e82d1d3f676db2 100644 +--- a/net/minecraft/world/level/chunk/Strategy.java ++++ b/net/minecraft/world/level/chunk/Strategy.java +@@ -4,6 +4,15 @@ import net.minecraft.core.IdMap; + import net.minecraft.util.Mth; + + public abstract class Strategy { ++ // Leaf start - Lithium - faster hash palette ++ private static final Palette.Factory HASH = net.caffeinemc.mods.lithium.common.world.chunk.LithiumHashPalette::create; ++ //private static final Configuration HASH_3BIT = new Configuration.Simple(HASH, 3); ++ private static final Configuration HASH_4BIT = new Configuration.Simple(HASH, 4); ++ private static final Configuration HASH_5BIT = new Configuration.Simple(HASH, 5); ++ private static final Configuration HASH_6BIT = new Configuration.Simple(HASH, 6); ++ private static final Configuration HASH_7BIT = new Configuration.Simple(HASH, 7); ++ private static final Configuration HASH_8BIT = new Configuration.Simple(HASH, 8); ++ // Leaf end - Lithium - faster hash palette + public static final Palette.Factory SINGLE_VALUE_PALETTE_FACTORY = SingleValuePalette::create; // Paper - Anti-Xray + private static final Palette.Factory LINEAR_PALETTE_FACTORY = LinearPalette::create; + private static final Palette.Factory HASHMAP_PALETTE_FACTORY = HashMapPalette::create; +@@ -36,11 +45,14 @@ public abstract class Strategy { + public Configuration getConfigurationForBitCount(final int entryBits) { + return switch (entryBits) { + case 0 -> Strategy.ZERO_BITS; +- case 1, 2, 3, 4 -> Strategy.FOUR_BITS_LINEAR; +- case 5 -> Strategy.FIVE_BITS_HASHMAP; +- case 6 -> Strategy.SIX_BITS_HASHMAP; +- case 7 -> Strategy.SEVEN_BITS_HASHMAP; +- case 8 -> Strategy.EIGHT_BITS_HASHMAP; ++ // Leaf start - Lithium - faster hash palette ++ case 1, 2 -> Strategy.FOUR_BITS_LINEAR; ++ case 3, 4 -> Strategy.HASH_4BIT; ++ case 5 -> Strategy.HASH_5BIT; ++ case 6 -> Strategy.HASH_6BIT; ++ case 7 -> Strategy.HASH_7BIT; ++ case 8 -> Strategy.HASH_8BIT; ++ // Leaf end - Lithium - faster hash palette + default -> new Configuration.Global(this.globalPaletteBitsInMemory, entryBits); + }; + } diff --git a/shiroha-server/minecraft-patches/features/0058-Leaves-Disable-packet-limit-Shiroha-Option-to-full-d.patch b/shiroha-server/minecraft-patches/features/0059-Leaves-Disable-packet-limit-Shiroha-Option-to-full-d.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0058-Leaves-Disable-packet-limit-Shiroha-Option-to-full-d.patch rename to shiroha-server/minecraft-patches/features/0059-Leaves-Disable-packet-limit-Shiroha-Option-to-full-d.patch diff --git a/shiroha-server/minecraft-patches/features/0059-Leaves-Configurable-collision-behavior.patch b/shiroha-server/minecraft-patches/features/0060-Leaves-Configurable-collision-behavior.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0059-Leaves-Configurable-collision-behavior.patch rename to shiroha-server/minecraft-patches/features/0060-Leaves-Configurable-collision-behavior.patch diff --git a/shiroha-server/minecraft-patches/features/0060-Leaves-Optimized-dragon-respawn.patch b/shiroha-server/minecraft-patches/features/0061-Leaves-Optimized-dragon-respawn.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0060-Leaves-Optimized-dragon-respawn.patch rename to shiroha-server/minecraft-patches/features/0061-Leaves-Optimized-dragon-respawn.patch diff --git a/shiroha-server/minecraft-patches/features/0061-Gale-Variable-entity-wake-up-duration.patch b/shiroha-server/minecraft-patches/features/0062-Gale-Variable-entity-wake-up-duration.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0061-Gale-Variable-entity-wake-up-duration.patch rename to shiroha-server/minecraft-patches/features/0062-Gale-Variable-entity-wake-up-duration.patch diff --git a/shiroha-server/minecraft-patches/features/0062-Gale-Replace-AI-attributes-with-optimized-collection.patch b/shiroha-server/minecraft-patches/features/0063-Gale-Replace-AI-attributes-with-optimized-collection.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0062-Gale-Replace-AI-attributes-with-optimized-collection.patch rename to shiroha-server/minecraft-patches/features/0063-Gale-Replace-AI-attributes-with-optimized-collection.patch diff --git a/shiroha-server/minecraft-patches/features/0063-Gale-Skip-entity-move-if-movement-is-zero.patch b/shiroha-server/minecraft-patches/features/0064-Gale-Skip-entity-move-if-movement-is-zero.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0063-Gale-Skip-entity-move-if-movement-is-zero.patch rename to shiroha-server/minecraft-patches/features/0064-Gale-Skip-entity-move-if-movement-is-zero.patch diff --git a/shiroha-server/minecraft-patches/features/0064-Gale-Store-mob-counts-in-an-array.patch b/shiroha-server/minecraft-patches/features/0065-Gale-Store-mob-counts-in-an-array.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0064-Gale-Store-mob-counts-in-an-array.patch rename to shiroha-server/minecraft-patches/features/0065-Gale-Store-mob-counts-in-an-array.patch diff --git a/shiroha-server/minecraft-patches/features/0065-Gale-Optimize-random-calls-in-chunk-ticking.patch b/shiroha-server/minecraft-patches/features/0066-Gale-Optimize-random-calls-in-chunk-ticking.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0065-Gale-Optimize-random-calls-in-chunk-ticking.patch rename to shiroha-server/minecraft-patches/features/0066-Gale-Optimize-random-calls-in-chunk-ticking.patch diff --git a/shiroha-server/minecraft-patches/features/0066-Gale-Reduce-enderman-teleport-chunk-lookups.patch b/shiroha-server/minecraft-patches/features/0067-Gale-Reduce-enderman-teleport-chunk-lookups.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0066-Gale-Reduce-enderman-teleport-chunk-lookups.patch rename to shiroha-server/minecraft-patches/features/0067-Gale-Reduce-enderman-teleport-chunk-lookups.patch diff --git a/shiroha-server/minecraft-patches/features/0067-Gale-Cache-ShapePairKey-hash.patch b/shiroha-server/minecraft-patches/features/0068-Gale-Cache-ShapePairKey-hash.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0067-Gale-Cache-ShapePairKey-hash.patch rename to shiroha-server/minecraft-patches/features/0068-Gale-Cache-ShapePairKey-hash.patch diff --git a/shiroha-server/minecraft-patches/features/0068-Gale-For-collision-check-has-physics-before-same-veh.patch b/shiroha-server/minecraft-patches/features/0069-Gale-For-collision-check-has-physics-before-same-veh.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0068-Gale-For-collision-check-has-physics-before-same-veh.patch rename to shiroha-server/minecraft-patches/features/0069-Gale-For-collision-check-has-physics-before-same-veh.patch diff --git a/shiroha-server/minecraft-patches/features/0069-Gale-Skip-negligible-planar-movement-multiplication.patch b/shiroha-server/minecraft-patches/features/0070-Gale-Skip-negligible-planar-movement-multiplication.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0069-Gale-Skip-negligible-planar-movement-multiplication.patch rename to shiroha-server/minecraft-patches/features/0070-Gale-Skip-negligible-planar-movement-multiplication.patch diff --git a/shiroha-server/minecraft-patches/features/0070-Gale-Optimize-matching-item-checks.patch b/shiroha-server/minecraft-patches/features/0071-Gale-Optimize-matching-item-checks.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0070-Gale-Optimize-matching-item-checks.patch rename to shiroha-server/minecraft-patches/features/0071-Gale-Optimize-matching-item-checks.patch diff --git a/shiroha-server/minecraft-patches/features/0071-Gale-Reduce-lambda-and-Optional-allocation-in-Entity.patch b/shiroha-server/minecraft-patches/features/0072-Gale-Reduce-lambda-and-Optional-allocation-in-Entity.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0071-Gale-Reduce-lambda-and-Optional-allocation-in-Entity.patch rename to shiroha-server/minecraft-patches/features/0072-Gale-Reduce-lambda-and-Optional-allocation-in-Entity.patch diff --git a/shiroha-server/minecraft-patches/features/0072-Gale-Reduce-array-allocations.patch b/shiroha-server/minecraft-patches/features/0073-Gale-Reduce-array-allocations.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0072-Gale-Reduce-array-allocations.patch rename to shiroha-server/minecraft-patches/features/0073-Gale-Reduce-array-allocations.patch diff --git a/shiroha-server/minecraft-patches/features/0073-Some-optimizations-from-krypton.patch b/shiroha-server/minecraft-patches/features/0074-Some-optimizations-from-krypton.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0073-Some-optimizations-from-krypton.patch rename to shiroha-server/minecraft-patches/features/0074-Some-optimizations-from-krypton.patch diff --git a/shiroha-server/minecraft-patches/features/0074-Frustum-filtering-tracker.patch b/shiroha-server/minecraft-patches/features/0075-Frustum-filtering-tracker.patch similarity index 100% rename from shiroha-server/minecraft-patches/features/0074-Frustum-filtering-tracker.patch rename to shiroha-server/minecraft-patches/features/0075-Frustum-filtering-tracker.patch diff --git a/shiroha-server/src/main/java/net/caffeinemc/mods/lithium/common/world/chunk/LithiumHashPalette.java b/shiroha-server/src/main/java/net/caffeinemc/mods/lithium/common/world/chunk/LithiumHashPalette.java new file mode 100644 index 0000000..1c00e36 --- /dev/null +++ b/shiroha-server/src/main/java/net/caffeinemc/mods/lithium/common/world/chunk/LithiumHashPalette.java @@ -0,0 +1,224 @@ +// Leaf - Lithium - faster hash palette + +package net.caffeinemc.mods.lithium.common.world.chunk; + +import ca.spottedleaf.moonrise.patches.fast_palette.FastPalette; +import ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData; +import it.unimi.dsi.fastutil.HashCommon; +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; +import net.minecraft.CrashReport; +import net.minecraft.CrashReportCategory; +import net.minecraft.ReportedException; +import net.minecraft.core.IdMap; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.VarInt; +import net.minecraft.world.level.chunk.HashMapPalette; +import net.minecraft.world.level.chunk.MissingPaletteEntryException; +import net.minecraft.world.level.chunk.Palette; +import net.minecraft.world.level.chunk.PaletteResize; +import org.jspecify.annotations.NullMarked; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; + +import static it.unimi.dsi.fastutil.Hash.FAST_LOAD_FACTOR; + +/** + * Generally provides better performance over the vanilla {@link net.minecraft.world.level.chunk.HashMapPalette} when calling + * {@link LithiumHashPalette#idFor(Object, PaletteResize)} through using a faster backing map and reducing pointer chasing. + */ +@NullMarked +public final class LithiumHashPalette extends HashMapPalette implements Palette, FastPalette { + private static final int ABSENT_VALUE = -1; + + private final int indexBits; + + private final Reference2IntOpenHashMap table; + private T[] entries; + private int size = 0; + + private LithiumHashPalette(int indexBits, T[] entries, Reference2IntOpenHashMap table, int size) { + super(size, true); + this.indexBits = indexBits; + this.entries = entries; + this.table = table; + this.size = size; + } + + public LithiumHashPalette(int bits, List list) { + this(bits); + + for (T t : list) { + this.addEntry(t); + } + } + + @SuppressWarnings("unchecked") + public LithiumHashPalette(int bits) { + super(bits, true); + this.indexBits = bits; + + int capacity = 1 << bits; + + this.entries = (T[]) new Object[capacity]; + this.table = new Reference2IntOpenHashMap<>(capacity, FAST_LOAD_FACTOR); + this.table.defaultReturnValue(ABSENT_VALUE); + } + + // Leaf start - Sync moonrise changes + @Override + public T[] moonrise$getRawPalette(final FastPaletteData container) { + return this.entries; + } + // Leaf end - Sync moonrise changes + + @Override + public int idFor(T obj, PaletteResize paletteResize) { + int id = this.table.getInt(obj); + + if (id == ABSENT_VALUE) { + id = this.computeEntry(obj, paletteResize); + } + + return id; + } + + @Override + public boolean maybeHas(Predicate predicate) { + for (int i = 0; i < this.size; ++i) { + if (predicate.test(this.entries[i])) { + return true; + } + } + + return false; + } + + private int computeEntry(T obj, PaletteResize paletteResize) { + int id = this.addEntry(obj); + + if (id >= 1 << this.indexBits) { + if (paletteResize == null) { + throw new IllegalStateException("Cannot grow"); + } else { + id = paletteResize.onResize(this.indexBits + 1, obj); + } + } + + return id; + } + + private int addEntry(T obj) { + int nextId = this.size; + + if (nextId >= this.entries.length) { + this.resize(this.size); + } + + this.table.put(obj, nextId); + this.entries[nextId] = obj; + + this.size++; + + return nextId; + } + + private void resize(int neededCapacity) { + this.entries = Arrays.copyOf(this.entries, HashCommon.nextPowerOfTwo(neededCapacity + 1)); + } + + @Override + public T valueFor(int id) { + T[] entries = this.entries; + + T entry = null; + if (id >= 0 && id < entries.length) { + entry = entries[id]; + } + + if (entry != null) { + return entry; + } else { + throw this.missingPaletteEntryCrash(id); + } + } + + private ReportedException missingPaletteEntryCrash(int id) { + try { + throw new MissingPaletteEntryException(id); + } catch (MissingPaletteEntryException e) { + CrashReport crashReport = CrashReport.forThrowable(e, "[Lithium] Getting Palette Entry"); + CrashReportCategory crashReportCategory = crashReport.addCategory("Chunk section"); + crashReportCategory.setDetail("IndexBits", this.indexBits); + crashReportCategory.setDetail("Entries", this.entries.length + " Elements: " + Arrays.toString(this.entries)); + crashReportCategory.setDetail("Table", this.table.size() + " Elements: " + this.table); + return new ReportedException(crashReport); + } + } + + @Override + public void read(FriendlyByteBuf buf, IdMap idMap) { + this.clear(); + + int entryCount = buf.readVarInt(); + + for (int i = 0; i < entryCount; ++i) { + this.addEntry(idMap.byIdOrThrow(buf.readVarInt())); + } + } + + @Override + public void write(FriendlyByteBuf buf, IdMap idMap) { + int size = this.size; + buf.writeVarInt(size); + + for (int i = 0; i < size; ++i) { + buf.writeVarInt(idMap.getId(this.valueFor(i))); + } + } + + @Override + public int getSerializedSize(IdMap idMap) { + int size = VarInt.getByteSize(this.size); + + for (int i = 0; i < this.size; ++i) { + size += VarInt.getByteSize(idMap.getId(this.valueFor(i))); + } + + return size; + } + + @Override + public int getSize() { + return this.size; + } + + @Override + public Palette copy() { + return new LithiumHashPalette<>(this.indexBits, this.entries.clone(), this.table.clone(), this.size); + } + + private void clear() { + Arrays.fill(this.entries, null); + this.table.clear(); + this.size = 0; + } + + public List getElements() { + T[] copy = Arrays.copyOf(this.entries, this.size); + return Arrays.asList(copy); + } + + // Leaf start - override getEntries + @Override + public List getEntries() { + T[] copy = Arrays.copyOf(this.entries, this.size); + return Arrays.asList(copy); + } + // Leaf end - override getEntries + + public static Palette create(int bits, List list) { + return new LithiumHashPalette<>(bits, list); + } +} \ No newline at end of file