diff --git a/Spigot-Server-Patches/0505-Optimize-Light-Engine.patch b/Spigot-Server-Patches/0505-Optimize-Light-Engine.patch index 31bf1a582..83d084253 100644 --- a/Spigot-Server-Patches/0505-Optimize-Light-Engine.patch +++ b/Spigot-Server-Patches/0505-Optimize-Light-Engine.patch @@ -1027,21 +1027,21 @@ index a35e7b392c74fadf2760d1fc2021e98d33858cb5..944094e8e770cc8c0205ef2aa6c48fff lightenginelayer.a(Long.MAX_VALUE, l3, 15, false); } diff --git a/src/main/java/net/minecraft/server/LightEngineThreaded.java b/src/main/java/net/minecraft/server/LightEngineThreaded.java -index a9dc8466278f9ec2becbcb643e6e1c973df72b82..721f86a5405c9575d8ee3fc661395e65487b6d96 100644 +index a9dc8466278f9ec2becbcb643e6e1c973df72b82..97c41fa1306798dad08ad9797c61f13d0dff6f52 100644 --- a/src/main/java/net/minecraft/server/LightEngineThreaded.java +++ b/src/main/java/net/minecraft/server/LightEngineThreaded.java -@@ -14,8 +14,98 @@ import org.apache.logging.log4j.Logger; - public class LightEngineThreaded extends LightEngine implements AutoCloseable { +@@ -15,15 +15,119 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { private static final Logger LOGGER = LogManager.getLogger(); -- private final ThreadedMailbox b; + private final ThreadedMailbox b; - private final ObjectList> c = new ObjectArrayList(); -+ private final ThreadedMailbox b; ThreadedMailbox mailbox; // Paper +- private final PlayerChunkMap d; + // Paper start + private static final int MAX_PRIORITIES = PlayerChunkMap.GOLDEN_TICKET + 2; ++ private final java.util.concurrent.ConcurrentLinkedQueue priorityChanges = new java.util.concurrent.ConcurrentLinkedQueue<>(); + + public void changePriority(long pair, int currentPriority, int priority) { -+ this.mailbox.queue(() -> { ++ this.priorityChanges.add(() -> { + ChunkLightQueue remove = this.queue.buckets[currentPriority].remove(pair); + if (remove != null) { + ChunkLightQueue existing = this.queue.buckets[priority].put(pair, remove); @@ -1053,6 +1053,15 @@ index a9dc8466278f9ec2becbcb643e6e1c973df72b82..721f86a5405c9575d8ee3fc661395e65 + }); + } + ++ private boolean isChunkLightStatus(long pair) { ++ PlayerChunk playerChunk = playerChunkMap.getUpdatingChunk(pair); ++ if (playerChunk == null) { ++ return false; ++ } ++ ChunkStatus status = PlayerChunk.getChunkStatus(playerChunk.getTicketLevel()); ++ return status != null && status.isAtLeastStatus(ChunkStatus.LIGHT); ++ } ++ + static class ChunkLightQueue { + public boolean shouldFastUpdate; + java.util.ArrayDeque pre = new java.util.ArrayDeque(); @@ -1063,7 +1072,7 @@ index a9dc8466278f9ec2becbcb643e6e1c973df72b82..721f86a5405c9575d8ee3fc661395e65 + + + // Retain the chunks priority level for queued light tasks -+ private static class LightQueue { ++ private class LightQueue { + private int size = 0; + private int lowestPriority = MAX_PRIORITIES; + private final it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap[] buckets = new it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap[MAX_PRIORITIES]; @@ -1103,6 +1112,10 @@ index a9dc8466278f9ec2becbcb643e6e1c973df72b82..721f86a5405c9575d8ee3fc661395e65 + } + + public boolean poll(java.util.List pre, java.util.List post) { ++ Runnable run; ++ while ((run = priorityChanges.poll()) != null) { ++ run.run(); ++ } + boolean hasWork = false; + it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap[] buckets = this.buckets; + while (lowestPriority < MAX_PRIORITIES && !isEmpty()) { @@ -1128,49 +1141,69 @@ index a9dc8466278f9ec2becbcb643e6e1c973df72b82..721f86a5405c9575d8ee3fc661395e65 + + private final LightQueue queue = new LightQueue(); + // Paper end - private final PlayerChunkMap d; ++ private final PlayerChunkMap d; private final PlayerChunkMap playerChunkMap; // Paper private final Mailbox> e; private volatile int f = 5; -@@ -25,7 +115,7 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { - super(ilightaccess, true, flag); - this.d = playerchunkmap; - this.e = mailbox; -- this.b = threadedmailbox; -+ this.mailbox = this.b = threadedmailbox; // Paper - } + private final AtomicBoolean g = new AtomicBoolean(); - public void close() {} -@@ -111,8 +201,11 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { + public LightEngineThreaded(ILightAccess ilightaccess, PlayerChunkMap playerchunkmap, boolean flag, ThreadedMailbox threadedmailbox, Mailbox> mailbox) { + super(ilightaccess, true, flag); +- this.d = playerchunkmap; ++ this.d = playerchunkmap; this.playerChunkMap = d; // Paper + this.e = mailbox; + this.b = threadedmailbox; + } +@@ -111,10 +215,10 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { private void a(int i, int j, IntSupplier intsupplier, LightEngineThreaded.Update lightenginethreaded_update, Runnable runnable) { this.e.a(ChunkTaskQueueSorter.a(() -> { - this.c.add(Pair.of(lightenginethreaded_update, runnable)); - if (this.c.size() >= this.f) { +- this.b(); +- } + // Paper start + int priority = intsupplier.getAsInt(); -+ this.queue.add(ChunkCoordIntPair.pair(i, j), priority, lightenginethreaded_update, runnable); // Paper -+ if (priority <= 25) { // don't auto kick off unless priority -+ // Paper end - this.b(); - } ++ this.queue.add(ChunkCoordIntPair.pair(i, j), priority, lightenginethreaded_update, runnable); ++ // Paper end -@@ -134,7 +227,13 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { + }, ChunkCoordIntPair.pair(i, j), intsupplier)); + } +@@ -133,8 +237,27 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { + public CompletableFuture a(IChunkAccess ichunkaccess, boolean flag) { ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); - ichunkaccess.b(false); +- ichunkaccess.b(false); - this.a(chunkcoordintpair.x, chunkcoordintpair.z, LightEngineThreaded.Update.PRE_UPDATE, SystemUtils.a(() -> { + // Paper start ++ //ichunkaccess.b(false); // Don't need to disable this + long pair = chunkcoordintpair.pair(); + CompletableFuture future = new CompletableFuture<>(); -+ IntSupplier prioritySupplier = d.getPrioritySupplier(pair); ++ IntSupplier prioritySupplier = playerChunkMap.getPrioritySupplier(pair); + this.e.a(ChunkTaskQueueSorter.a(() -> { ++ // Chunk's no longer needed ++ if (!isChunkLightStatus(pair)) { ++ this.d.c(chunkcoordintpair); // copied from end of method to release light ticket ++ future.complete(ichunkaccess); ++ return; ++ } ++ boolean[] skippedPre = {false}; + this.queue.add(pair, prioritySupplier.getAsInt(), LightEngineThreaded.Update.PRE_UPDATE, SystemUtils.a(() -> { ++ if (!isChunkLightStatus(pair)) { ++ this.d.c(chunkcoordintpair); // copied from end of method to release light ticket ++ future.complete(ichunkaccess); ++ skippedPre[0] = true; ++ return; ++ } + // Paper end ChunkSection[] achunksection = ichunkaccess.getSections(); for (int i = 0; i < 16; ++i) { -@@ -155,52 +254,51 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { - this.d.c(chunkcoordintpair); +@@ -152,55 +275,55 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { + }); + } + +- this.d.c(chunkcoordintpair); ++ this.d.c(chunkcoordintpair); // Paper - if change, copy into !isChunkLightStatus above }, () -> { return "lightChunk " + chunkcoordintpair + " " + flag; + // Paper start - merge the 2 together @@ -1178,6 +1211,7 @@ index a9dc8466278f9ec2becbcb643e6e1c973df72b82..721f86a5405c9575d8ee3fc661395e65 - return CompletableFuture.supplyAsync(() -> { + + this.queue.add(pair, prioritySupplier.getAsInt(), LightEngineThreaded.Update.POST_UPDATE, () -> { ++ if (skippedPre[0]) return; // Paper - future's already complete ichunkaccess.b(true); super.b(chunkcoordintpair, false); - return ichunkaccess; @@ -1280,7 +1314,7 @@ index 446c401b3139f8c6c0e70d883340f0140d94b752..a3bce8f13bf278af2d6870891daa9bf6 if (getCurrentPriority() != priority) { this.v.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 2fac2e59ab0712459f03cdacc0f67c1528c5a5bf..5544254a655485b8ef9d2883da4d722fa57c63d9 100644 +index fea219dcfd5a98fc0e48fd70dc7d0fd41b2fc970..ad8a00e0fb5da5df1eb3afbf9ea50acfc89a5ff1 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -653,6 +653,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {