aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0835-Cache-palette-array.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/server/0835-Cache-palette-array.patch')
-rw-r--r--patches/server/0835-Cache-palette-array.patch61
1 files changed, 61 insertions, 0 deletions
diff --git a/patches/server/0835-Cache-palette-array.patch b/patches/server/0835-Cache-palette-array.patch
new file mode 100644
index 0000000000..2c787bbbc6
--- /dev/null
+++ b/patches/server/0835-Cache-palette-array.patch
@@ -0,0 +1,61 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Paul Sauve <[email protected]>
+Date: Thu, 4 Feb 2021 23:28:46 -0600
+Subject: [PATCH] Cache palette array
+
+Instead of allocating the 4KB for every chunk section, cache it locally and
+reuse it for other chunk sections to save on allocations. These allocations add
+up very quickly when saving chunks frequently.
+
+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 c9e942669458668a184aaec3bc0a5509dd6ab5f0..ac84d49d7819666a89cacbe9ef1199cf22ac2ac3 100644
+--- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
++++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
+@@ -263,13 +263,17 @@ public class PalettedContainer<T> implements PaletteResize<T> {
+
+ }
+
++ // Paper start - allow reusing int array
+ public synchronized void write(CompoundTag nbt, String paletteKey, String dataKey) { // Paper - synchronize
++ this.write(nbt, paletteKey, dataKey, new int[4096]);
++ }
++ public synchronized void write(CompoundTag nbt, String paletteKey, String dataKey, int[] is) { // Paper - synchronize // Paper end
+ try {
+ this.acquire();
+ HashMapPalette<T> hashMapPalette = new HashMapPalette<>(this.registry, this.bits, this.dummyPaletteResize, this.reader, this.writer);
+ T object = this.defaultValue;
+ int i = hashMapPalette.idFor(this.defaultValue);
+- int[] is = new int[4096];
++ //int[] is = new int[4096]; // Paper - will now be pulled from ThreadLocal
+
+ for(int j = 0; j < 4096; ++j) {
+ T object2 = this.get(j);
+diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+index 7921ee2786d0d6a60d43786b20efc03a0f9178e3..10f15b8c7763a980aec47a4b4dda5686e60642ce 100644
+--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
++++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+@@ -500,6 +500,7 @@ public class ChunkSerializer {
+ return new AsyncSaveData(blockLight, skyLight, blockTickListSerialized, fluidTickListSerialized, blockEntitiesSerialized, world.getGameTime());
+ }
+
++ private static final ThreadLocal<int[]> PALETTE_ARRAY = ThreadLocal.withInitial(() -> new int[4096]); // Paper - maintain a per-thread cache for saving palettes
+ public static CompoundTag write(ServerLevel world, ChunkAccess chunk) {
+ return saveChunk(world, chunk, null);
+ }
+@@ -533,6 +534,7 @@ public class ChunkSerializer {
+ ThreadedLevelLightEngine lightenginethreaded = world.getChunkSource().getLightEngine();
+ boolean flag = chunk.isLightCorrect();
+
++ int[] is = PALETTE_ARRAY.get(); // Paper - use cached
+ for (int i = lightenginethreaded.getMinLightSection(); i < lightenginethreaded.getMaxLightSection(); ++i) {
+ int finalI = i; // CraftBukkit - decompile errors
+ LevelChunkSection chunksection = (LevelChunkSection) Arrays.stream(achunksection).filter((chunksection1) -> {
+@@ -547,7 +549,7 @@ public class ChunkSerializer {
+
+ nbttagcompound2.putByte("Y", (byte) (i & 255));
+ if (chunksection != LevelChunk.EMPTY_SECTION) {
+- chunksection.getStates().write(nbttagcompound2, "Palette", "BlockStates");
++ chunksection.getStates().write(nbttagcompound2, "Palette", "BlockStates", is); // Paper - reuse array
+ }
+
+ // Paper start - replace light engine