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 <Spottedleaf@users.noreply.github.com>
This commit is contained in:
Spottedleaf 2021-08-27 19:20:31 -07:00
parent 0f34801f3d
commit 6522a6eed1
2 changed files with 15 additions and 11 deletions

View File

@ -109,6 +109,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ volatile int priorityBoost = 0;
+ public final java.util.concurrent.ConcurrentHashMap<ChunkHolder, ChunkStatus> neighbors = new java.util.concurrent.ConcurrentHashMap<>();
+ public final it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<Integer> 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<CompoundTag> 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) {

View File

@ -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