From 3cf6f06a21ceb2170dde24902cd3662d29667bb2 Mon Sep 17 00:00:00 2001 From: Aikar Date: Mon, 25 May 2020 11:08:11 -0400 Subject: [PATCH] Fix Spigot bug with chunk unloading Spigot inserted their Slack Activity Accountant in the wrong location resulting in a chunk being removed from the unload queue, inserted into the unload map, but never calling the function to finish the removal.... This caused the chunk to become stuck in the unload map if ever hit, because the unload map was meant to be a TEMPORARY location while it was saving. Fix this by abort iteration AFTER the current chunk is finisehd processing Also, improve how aggressive we are at unloading chunks, targetting 10% per tick instead. These saves are asynchronous so there should be less of a hit here. --- .../Asynchronous-chunk-IO-and-loading.patch | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch index 5890301d6..84f5d3cbc 100644 --- a/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch +++ b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch @@ -3165,6 +3165,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } else { this.visibleChunks.values().stream().filter(PlayerChunk::hasBeenLoaded).forEach((playerchunk) -> { @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + + } + +- private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.96; // Spigot ++ private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.90; // Spigot // Paper - unload more + protected void unloadChunks(BooleanSupplier booleansupplier) { GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler(); @@ -3181,6 +3187,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 gameprofilerfiller.exit(); @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + if (playerchunk != null) { + this.pendingUnload.put(j, playerchunk); + this.updatingChunksModified = true; ++ this.a(j, playerchunk); // Paper - Move up - don't leak chunks + // Spigot start + if (!booleansupplier.getAsBoolean() && this.unloadQueue.size() <= targetSize && activityAccountant.activityTimeIsExhausted()) { + break; + } + // Spigot end +- this.a(j, playerchunk); ++ //this.a(j, playerchunk); // Paper - move up because spigot did a dumb + } + } + activityAccountant.endActivity(); // Spigot +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { }