From 6522a6eed1f7060b8fbefca0326b71d2d5513e59 Mon Sep 17 00:00:00 2001 From: Spottedleaf <6100722+Spottedleaf@users.noreply.github.com> Date: Fri, 27 Aug 2021 19:20:31 -0700 Subject: [PATCH] Ensure priority updates are determined by current level, not deferred level (#6507) * Ensure priority updates are determined by current level, not deferred level Deferral could cause an infinite loop to occur. Also, re-add the light engine priority logic. * Rebase Co-authored-by: Spottedleaf --- ...-Chunk-Priority-Urgency-System-for-Chunks.patch | 14 +++++++++----- patches/server/Optimize-Light-Engine.patch | 12 ++++++------ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/patches/server/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch b/patches/server/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch index 83d01dc693..f99cf61cdf 100644 --- a/patches/server/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch +++ b/patches/server/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch @@ -109,6 +109,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + volatile int priorityBoost = 0; + public final java.util.concurrent.ConcurrentHashMap neighbors = new java.util.concurrent.ConcurrentHashMap<>(); + public final it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap neighborPriorities = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>(); ++ int requestedPriority = ChunkMap.MAX_CHUNK_DISTANCE + 1; // this priority is possible pending, but is used to ensure needless updates are not queued + + private int getDemandedPriority() { + int priority = neighborPriority; // if we have a neighbor priority, use it @@ -170,8 +171,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + private void setNeighborPriority(ChunkHolder requester, int priority) { + synchronized (neighborPriorities) { -+ neighborPriorities.put(requester.pos.toLong(), Integer.valueOf(priority)); -+ recalcNeighborPriority(); ++ if (!Integer.valueOf(priority).equals(neighborPriorities.put(requester.pos.toLong(), Integer.valueOf(priority)))) { ++ recalcNeighborPriority(); ++ } + } + checkPriority(); + } @@ -189,7 +191,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + private void checkPriority() { -+ if (queueLevel != getDemandedPriority()) this.chunkMap.queueHolderUpdate(this); ++ if (this.requestedPriority != getDemandedPriority()) this.chunkMap.queueHolderUpdate(this); + } + + public final double getDistance(ServerPlayer player) { @@ -324,7 +326,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + //this.onLevelChange.onLevelChange(this.pos, this::getQueueLevel, this.ticketLevel, this::setQueueLevel); + // Paper start - raise IO/load priority if priority changes, use our preferred priority + priorityBoost = chunkMap.distanceManager.getChunkPriority(pos); ++ int currRequestedPriority = this.requestedPriority; + int priority = getDemandedPriority(); ++ int newRequestedPriority = this.requestedPriority = priority; + if (this.queueLevel > priority) { + int ioPriority = com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY; + if (priority <= 10) { @@ -334,7 +338,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + chunkMap.level.asyncChunkTaskManager.raisePriority(pos.x, pos.z, ioPriority); + } -+ if (this.queueLevel != priority) { ++ if (currRequestedPriority != newRequestedPriority) { + this.onLevelChange.onLevelChange(this.pos, () -> this.queueLevel, priority, p -> this.queueLevel = p); // use preferred priority + int neighborsPriority = getNeighborsPriority(); + this.neighbors.forEach((neighbor, neighborDesired) -> neighbor.setNeighborPriority(this, neighborsPriority)); @@ -589,7 +593,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 CompletableFuture chunkSaveFuture = this.level.asyncChunkTaskManager.getChunkSaveFuture(pos.x, pos.z); + // Paper start + ChunkHolder playerChunk = getUpdatingChunkIfPresent(pos.toLong()); -+ int chunkPriority = playerChunk != null ? playerChunk.queueLevel : 33; ++ int chunkPriority = playerChunk != null ? playerChunk.requestedPriority : 33; + int priority = com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY; + + if (chunkPriority <= 10) { diff --git a/patches/server/Optimize-Light-Engine.patch b/patches/server/Optimize-Light-Engine.patch index 85b255f159..5ff50bbfde 100644 --- a/patches/server/Optimize-Light-Engine.patch +++ b/patches/server/Optimize-Light-Engine.patch @@ -29,13 +29,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java @@ -0,0 +0,0 @@ public class ChunkHolder { + ioPriority = com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGH_PRIORITY; + } + chunkMap.level.asyncChunkTaskManager.raisePriority(pos.x, pos.z, ioPriority); ++ chunkMap.level.getChunkSource().getLightEngine().queue.changePriority(pos.toLong(), this.queueLevel, priority); // Paper // Restore this in chunk priority later? } - // Paper end - this.oldTicketLevel = this.ticketLevel; -+ //chunkMap.level.getChunkSource().getLightEngine().queue.changePriority(pos.toLong(), this.queueLevel, priority); // Paper // Restore this in chunk priority later? - // CraftBukkit start - // ChunkLoadEvent: Called after the chunk is loaded: isChunkLoaded returns true and chunk is ready to be modified by plugins. - if (!playerchunk_state.isOrAfter(ChunkHolder.FullChunkStatus.BORDER) && playerchunk_state1.isOrAfter(ChunkHolder.FullChunkStatus.BORDER)) { + if (currRequestedPriority != newRequestedPriority) { + this.onLevelChange.onLevelChange(this.pos, () -> this.queueLevel, priority, p -> this.queueLevel = p); // use preferred priority diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java