9
0
mirror of https://github.com/LeavesMC/Leaves.git synced 2025-12-19 14:59:32 +00:00

fix: fix faster chunk serialization patch (#641)

* fix: fix faster chunk serialization patch

* fix: fix patch license

* fix: fix patch, config

* fix: fix patch, config

* fix: fix patch author and licnese
This commit is contained in:
MC_XiaoHei
2025-08-01 15:29:30 +08:00
committed by GitHub
parent e44e469a47
commit 5d653e319b

View File

@@ -1,11 +1,10 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martijn Muijsers <martijnmuijsers@live.nl> From: violetc <58360096+s-yh-china@users.noreply.github.com>
Date: Wed, 30 Nov 2022 21:51:16 +0100 Date: Tue, 18 Jul 2023 13:14:15 +0800
Subject: [PATCH] Faster chunk serialization Subject: [PATCH] Faster chunk serialization
This patch is Powered by Gale(https://github.com/GaleMC/Gale) This patch is Powered by Gale(https://github.com/GaleMC/Gale)
License: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html) License: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
Gale - https://galemc.org
This patch is based on the following mixins and classes: This patch is based on the following mixins and classes:
* "net/caffeinemc/mods/lithium/common/world/chunk/CompactingPackedIntegerArray.java" * "net/caffeinemc/mods/lithium/common/world/chunk/CompactingPackedIntegerArray.java"
@@ -17,7 +16,7 @@ As part of: Lithium (https://github.com/CaffeineMC/lithium-fabric)
Licensed under: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html) Licensed under: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html)
diff --git a/net/minecraft/util/BitStorage.java b/net/minecraft/util/BitStorage.java diff --git a/net/minecraft/util/BitStorage.java b/net/minecraft/util/BitStorage.java
index 02502d50f0255f5bbcc0ecb965abb48cc1a112da..e1f4ca261d106d176298b2afc016f5168abaa06b 100644 index 02502d50f0255f5bbcc0ecb965abb48cc1a112da..674d714ba21fa0306283dae35ece466dcfcbdf6c 100644
--- a/net/minecraft/util/BitStorage.java --- a/net/minecraft/util/BitStorage.java
+++ b/net/minecraft/util/BitStorage.java +++ b/net/minecraft/util/BitStorage.java
@@ -38,4 +38,6 @@ public interface BitStorage extends ca.spottedleaf.moonrise.patches.block_counti @@ -38,4 +38,6 @@ public interface BitStorage extends ca.spottedleaf.moonrise.patches.block_counti
@@ -25,10 +24,10 @@ index 02502d50f0255f5bbcc0ecb965abb48cc1a112da..e1f4ca261d106d176298b2afc016f516
} }
// Paper end - block counting // Paper end - block counting
+ +
+ <T> void compact(net.minecraft.world.level.chunk.Palette<T> srcPalette, net.minecraft.world.level.chunk.Palette<T> dstPalette, short[] out); // Gale - Lithium - faster chunk serialization + <T> void compact(net.minecraft.world.level.chunk.Palette<T> srcPalette, net.minecraft.world.level.chunk.Palette<T> dstPalette, short[] out); // Leaves - Gale - Lithium - faster chunk serialization
} }
diff --git a/net/minecraft/util/SimpleBitStorage.java b/net/minecraft/util/SimpleBitStorage.java diff --git a/net/minecraft/util/SimpleBitStorage.java b/net/minecraft/util/SimpleBitStorage.java
index e6306a68c8652d4c5d22d5ecb1416f5f931f76ee..8091f0c0a536047ead4966e70785962e87faad9a 100644 index e6306a68c8652d4c5d22d5ecb1416f5f931f76ee..bbebf19cfc78d31319948943fa3fea5229f4aaf3 100644
--- a/net/minecraft/util/SimpleBitStorage.java --- a/net/minecraft/util/SimpleBitStorage.java
+++ b/net/minecraft/util/SimpleBitStorage.java +++ b/net/minecraft/util/SimpleBitStorage.java
@@ -465,4 +465,45 @@ public class SimpleBitStorage implements BitStorage { @@ -465,4 +465,45 @@ public class SimpleBitStorage implements BitStorage {
@@ -36,7 +35,7 @@ index e6306a68c8652d4c5d22d5ecb1416f5f931f76ee..8091f0c0a536047ead4966e70785962e
} }
} }
+ +
+ // Gale start - Lithium - faster chunk serialization + // Leaves start - Gale - Lithium - faster chunk serialization
+ @Override + @Override
+ public <T> void compact(net.minecraft.world.level.chunk.Palette<T> srcPalette, net.minecraft.world.level.chunk.Palette<T> dstPalette, short[] out) { + public <T> void compact(net.minecraft.world.level.chunk.Palette<T> srcPalette, net.minecraft.world.level.chunk.Palette<T> dstPalette, short[] out) {
+ if (this.size >= Short.MAX_VALUE) { + if (this.size >= Short.MAX_VALUE) {
@@ -74,11 +73,11 @@ index e6306a68c8652d4c5d22d5ecb1416f5f931f76ee..8091f0c0a536047ead4966e70785962e
+ } + }
+ } + }
+ } + }
+ // Gale end - Lithium - faster chunk serialization + // Leaves end - Gale - Lithium - faster chunk serialization
+ +
} }
diff --git a/net/minecraft/util/ZeroBitStorage.java b/net/minecraft/util/ZeroBitStorage.java diff --git a/net/minecraft/util/ZeroBitStorage.java b/net/minecraft/util/ZeroBitStorage.java
index 09fd99c9cbd23b5f3c899bfb00c9b89651948ed8..0066476f5e8289f0702ba3e525397419ef8b44ae 100644 index 09fd99c9cbd23b5f3c899bfb00c9b89651948ed8..d58539fe376f548930b49141c87ec5eb23b29af7 100644
--- a/net/minecraft/util/ZeroBitStorage.java --- a/net/minecraft/util/ZeroBitStorage.java
+++ b/net/minecraft/util/ZeroBitStorage.java +++ b/net/minecraft/util/ZeroBitStorage.java
@@ -80,4 +80,6 @@ public class ZeroBitStorage implements BitStorage { @@ -80,4 +80,6 @@ public class ZeroBitStorage implements BitStorage {
@@ -86,7 +85,7 @@ index 09fd99c9cbd23b5f3c899bfb00c9b89651948ed8..0066476f5e8289f0702ba3e525397419
} }
// Paper end - block counting // Paper end - block counting
+ +
+ @Override public <T> void compact(net.minecraft.world.level.chunk.Palette<T> srcPalette, net.minecraft.world.level.chunk.Palette<T> dstPalette, short[] out) {} // Gale - Lithium - faster chunk serialization + @Override public <T> void compact(net.minecraft.world.level.chunk.Palette<T> srcPalette, net.minecraft.world.level.chunk.Palette<T> dstPalette, short[] out) {} // Leaves - Gale - Lithium - faster chunk serialization
} }
diff --git a/net/minecraft/world/level/chunk/PaletteResize.java b/net/minecraft/world/level/chunk/PaletteResize.java diff --git a/net/minecraft/world/level/chunk/PaletteResize.java b/net/minecraft/world/level/chunk/PaletteResize.java
index c723606fa0be811e580ba47de8c9c575583cc930..2483210ca43221feaa5a2f1ced5c59731d5189fc 100644 index c723606fa0be811e580ba47de8c9c575583cc930..2483210ca43221feaa5a2f1ced5c59731d5189fc 100644
@@ -100,7 +99,7 @@ index c723606fa0be811e580ba47de8c9c575583cc930..2483210ca43221feaa5a2f1ced5c5973
int onResize(int bits, T objectAdded); int onResize(int bits, T objectAdded);
} }
diff --git a/net/minecraft/world/level/chunk/PalettedContainer.java b/net/minecraft/world/level/chunk/PalettedContainer.java diff --git a/net/minecraft/world/level/chunk/PalettedContainer.java b/net/minecraft/world/level/chunk/PalettedContainer.java
index a251ba67644cd02a0b00d7c8b0e2c64aa5e26291..59d48e7dc0911557c57a7e07f5f9013c010165bd 100644 index a251ba67644cd02a0b00d7c8b0e2c64aa5e26291..a826aff16aee6692ca07d485ab3c79c1c4a38b52 100644
--- a/net/minecraft/world/level/chunk/PalettedContainer.java --- a/net/minecraft/world/level/chunk/PalettedContainer.java
+++ b/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/net/minecraft/world/level/chunk/PalettedContainer.java
@@ -24,6 +24,22 @@ import net.minecraft.util.ThreadingDetector; @@ -24,6 +24,22 @@ import net.minecraft.util.ThreadingDetector;
@@ -108,7 +107,7 @@ index a251ba67644cd02a0b00d7c8b0e2c64aa5e26291..59d48e7dc0911557c57a7e07f5f9013c
public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainerRO<T> { public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainerRO<T> {
+ +
+ // Gale start - Lithium - faster chunk serialization + // Leaves start - Gale - Lithium - faster chunk serialization
+ private static final ThreadLocal<short[]> CACHED_ARRAY_4096 = ThreadLocal.withInitial(() -> new short[4096]); + private static final ThreadLocal<short[]> CACHED_ARRAY_4096 = ThreadLocal.withInitial(() -> new short[4096]);
+ private static final ThreadLocal<short[]> CACHED_ARRAY_64 = ThreadLocal.withInitial(() -> new short[64]); + private static final ThreadLocal<short[]> CACHED_ARRAY_64 = ThreadLocal.withInitial(() -> new short[64]);
+ private Optional<LongStream> asOptional(long[] data) { + private Optional<LongStream> asOptional(long[] data) {
@@ -121,82 +120,69 @@ index a251ba67644cd02a0b00d7c8b0e2c64aa5e26291..59d48e7dc0911557c57a7e07f5f9013c
+ default -> new short[size]; + default -> new short[size];
+ }; + };
+ } + }
+ // Gale end - Lithium - faster chunk serialization + // Leaves end - Gale - Lithium - faster chunk serialization
+ +
private static final int MIN_PALETTE_BITS = 0; private static final int MIN_PALETTE_BITS = 0;
private final PaletteResize<T> dummyPaletteResize = (bits, objectAdded) -> 0; private final PaletteResize<T> dummyPaletteResize = (bits, objectAdded) -> 0;
public final IdMap<T> registry; public final IdMap<T> registry;
@@ -343,28 +359,54 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer @@ -343,6 +359,56 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
public synchronized PalettedContainerRO.PackedData<T> pack(IdMap<T> registry, PalettedContainer.Strategy strategy) { // Paper - synchronize public synchronized PalettedContainerRO.PackedData<T> pack(IdMap<T> registry, PalettedContainer.Strategy strategy) { // Paper - synchronize
this.acquire(); this.acquire();
- PalettedContainerRO.PackedData var12; + // Leaves start - Gale - Lithium - faster chunk serialization
+ // Gale start - Lithium - faster chunk serialization + if (org.leavesmc.leaves.LeavesConfig.performance.fasterChunkSerialization) {
+ Optional<LongStream> data = Optional.empty(); + Optional<LongStream> data = Optional.empty();
+ List<T> elements = null; + List<T> elements = null;
try { + try {
- HashMapPalette<T> hashMapPalette = new HashMapPalette<>(registry, this.data.storage.getBits(), this.dummyPaletteResize); + // The palette that will be serialized
- int size = strategy.size(); + org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette<T> hashPalette = null;
- int[] ints = new int[size];
- this.data.storage.unpack(ints);
- swapPalette(ints, id -> hashMapPalette.idFor(this.data.palette.valueFor(id)));
- int i = strategy.calculateBitsForSerialization(registry, hashMapPalette.getSize());
- Optional<LongStream> optional;
- if (i != 0) {
- SimpleBitStorage simpleBitStorage = new SimpleBitStorage(i, size, ints);
- optional = Optional.of(Arrays.stream(simpleBitStorage.getRaw()));
- } else {
- optional = Optional.empty();
+ // The palette that will be serialized
+ org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette<T> hashPalette = null;
+ +
+ final Palette<T> palette = this.data.palette(); + final Palette<T> palette = this.data.palette();
+ final BitStorage storage = this.data.storage(); + final BitStorage storage = this.data.storage();
+ if (storage instanceof ZeroBitStorage || palette.getSize() == 1) { + if (storage instanceof ZeroBitStorage || palette.getSize() == 1) {
+ // If the palette only contains one entry, don't attempt to repack it. + // If the palette only contains one entry, don't attempt to repack it.
+ elements = List.of(palette.valueFor(0)); + elements = List.of(palette.valueFor(0));
+ } else if (palette instanceof org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette<T> lithiumHashPalette) { + } else if (palette instanceof org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette<T> lithiumHashPalette) {
+ hashPalette = lithiumHashPalette; + hashPalette = lithiumHashPalette;
} + }
- var12 = new PalettedContainerRO.PackedData<>(hashMapPalette.getEntries(), optional);
+ if (elements == null) {
+ org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette<T> compactedPalette = new org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette<>(registry, storage.getBits(), this.dummyPaletteResize);
+ short[] array = this.getOrCreate(strategy.size());
+ +
+ storage.compact(this.data.palette(), compactedPalette, array); + if (elements == null) {
+ org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette<T> compactedPalette = new org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette<>(registry, storage.getBits(), this.dummyPaletteResize);
+ short[] array = this.getOrCreate(strategy.size());
+ +
+ // If the palette didn't change during compaction, do a simple copy of the data array + storage.compact(this.data.palette(), compactedPalette, array);
+ if (hashPalette != null && hashPalette.getSize() == compactedPalette.getSize() && storage.getBits() == strategy.calculateBitsForSerialization(registry, hashPalette.getSize())) { // paletteSize can de-sync from palette - see https://github.com/CaffeineMC/lithium-fabric/issues/279 +
+ data = this.asOptional(storage.getRaw().clone()); + // If the palette didn't change during compaction, do a simple copy of the data array
+ elements = hashPalette.getElements(); + if (hashPalette != null && hashPalette.getSize() == compactedPalette.getSize() && storage.getBits() == strategy.calculateBitsForSerialization(registry, hashPalette.getSize())) { // paletteSize can de-sync from palette - see https://github.com/CaffeineMC/lithium-fabric/issues/279
+ } else { + data = this.asOptional(storage.getRaw().clone());
+ int bits = strategy.calculateBitsForSerialization(registry, compactedPalette.getSize()); + elements = hashPalette.getElements();
+ if (bits != 0) { + } else {
+ // Re-pack the integer array as the palette has changed size + int bits = strategy.calculateBitsForSerialization(registry, compactedPalette.getSize());
+ SimpleBitStorage copy = new SimpleBitStorage(bits, array.length); + if (bits != 0) {
+ for (int i = 0; i < array.length; ++i) { + // Re-pack the integer array as the palette has changed size
+ copy.set(i, array[i]); + SimpleBitStorage copy = new SimpleBitStorage(bits, array.length);
+ for (int i = 0; i < array.length; ++i) {
+ copy.set(i, array[i]);
+ }
+
+ // We don't need to clone the data array as we are the sole owner of it
+ data = this.asOptional(copy.getRaw());
+ } + }
+ +
+ // We don't need to clone the data array as we are the sole owner of it + elements = compactedPalette.getElements();
+ data = this.asOptional(copy.getRaw());
+ } + }
+
+ elements = compactedPalette.getElements();
+ } + }
+ } finally {
+ this.release();
+ } + }
} finally { +
this.release(); + return new PalettedContainerRO.PackedData<>(elements, data);
} + }
+ // Leaves end - Gale - Lithium - faster chunk serialization
- return var12; PalettedContainerRO.PackedData var12;
+ return new PalettedContainerRO.PackedData<>(elements, data); try {
+ // Gale end - Lithium - faster chunk serialization HashMapPalette<T> hashMapPalette = new HashMapPalette<>(registry, this.data.storage.getBits(), this.dummyPaletteResize);
} @@ -404,13 +470,43 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
private static <T> void swapPalette(int[] bits, IntUnaryOperator operator) {
@@ -404,13 +446,33 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
@Override @Override
public void count(PalettedContainer.CountConsumer<T> countConsumer) { public void count(PalettedContainer.CountConsumer<T> countConsumer) {
@@ -206,7 +192,17 @@ index a251ba67644cd02a0b00d7c8b0e2c64aa5e26291..59d48e7dc0911557c57a7e07f5f9013c
- Int2IntOpenHashMap map = new Int2IntOpenHashMap(); - Int2IntOpenHashMap map = new Int2IntOpenHashMap();
- this.data.storage.getAll(id -> map.addTo(id, 1)); - this.data.storage.getAll(id -> map.addTo(id, 1));
- map.int2IntEntrySet().forEach(idEntry -> countConsumer.accept(this.data.palette.valueFor(idEntry.getIntKey()), idEntry.getIntValue())); - map.int2IntEntrySet().forEach(idEntry -> countConsumer.accept(this.data.palette.valueFor(idEntry.getIntKey()), idEntry.getIntValue()));
+ // Gale start - Lithium - faster chunk serialization + // Leaves start - Gale - Lithium - faster chunk serialization
+ if (!org.leavesmc.leaves.LeavesConfig.performance.fasterChunkSerialization) {
+ if (this.data.palette.getSize() == 1) {
+ countConsumer.accept(this.data.palette.valueFor(0), this.data.storage.getSize());
+ } else {
+ Int2IntOpenHashMap map = new Int2IntOpenHashMap();
+ this.data.storage.getAll(id -> map.addTo(id, 1));
+ map.int2IntEntrySet().forEach(idEntry -> countConsumer.accept(this.data.palette.valueFor(idEntry.getIntKey()), idEntry.getIntValue()));
+ }
+ return;
+ }
+ int len = this.data.palette().getSize(); + int len = this.data.palette().getSize();
+ +
+ // Do not allocate huge arrays if we're using a large palette + // Do not allocate huge arrays if we're using a large palette
@@ -232,7 +228,7 @@ index a251ba67644cd02a0b00d7c8b0e2c64aa5e26291..59d48e7dc0911557c57a7e07f5f9013c
+ countConsumer.accept(obj, counts[i]); + countConsumer.accept(obj, counts[i]);
+ } + }
} }
+ // Gale end - Lithium - faster chunk serialization + // Leaves end - Gale - Lithium - faster chunk serialization
} }
record Configuration<T>(Palette.Factory factory, int bits) { record Configuration<T>(Palette.Factory factory, int bits) {