Improvements to chunk priority / bug fixes
ensure we add missing player tickets even if already full status remove the player ticket throttler entirely... causes a lot of issues and our system handles the role that it was serving now too. increase max delays on farther out chunks load delay remove -5 priority delay for distant chunks seemed it applied at weird times. ensure if delay distance manager tick ever got left lingering it unsets on a chunk load. Fixes #3572
This commit is contained in:
parent
a70618cd5c
commit
3dc5ad343f
|
@ -90,7 +90,7 @@ index f617636a22167b06ac8073aa25efd8c7099155f0..0f40793f004639822b9d40521cd21ec5
|
|||
return new BlockPosition(this.x << 4, 0, this.z << 4);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..02d07d3ff5c3b824047402ff1f58aa338a46c254 100644
|
||||
index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..f7be94e801e58a39e0efcc813d95bbd613afce03 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||
@@ -23,6 +23,7 @@ import java.util.concurrent.Executor;
|
||||
|
@ -121,13 +121,13 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..02d07d3ff5c3b824047402ff1f58aa33
|
|||
|
||||
// Paper start
|
||||
if (!this.pendingChunkUpdates.isEmpty()) {
|
||||
+ this.pollingPendingChunkUpdates = true;
|
||||
+ this.pollingPendingChunkUpdates = true; try {
|
||||
while(!this.pendingChunkUpdates.isEmpty()) {
|
||||
PlayerChunk remove = this.pendingChunkUpdates.remove();
|
||||
remove.isUpdateQueued = false;
|
||||
remove.a(playerchunkmap);
|
||||
}
|
||||
+ this.pollingPendingChunkUpdates = false;
|
||||
+ } finally { this.pollingPendingChunkUpdates = false; }
|
||||
// Paper end
|
||||
return true;
|
||||
} else {
|
||||
|
@ -163,7 +163,7 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..02d07d3ff5c3b824047402ff1f58aa33
|
|||
return removed; // CraftBukkit
|
||||
}
|
||||
|
||||
@@ -182,6 +191,116 @@ public abstract class ChunkMapDistance {
|
||||
@@ -182,6 +191,113 @@ public abstract class ChunkMapDistance {
|
||||
this.addTicketAtLevel(tickettype, chunkcoordintpair, i, t0);
|
||||
}
|
||||
|
||||
|
@ -201,16 +201,13 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..02d07d3ff5c3b824047402ff1f58aa33
|
|||
+ AsyncCatcher.catchOp("ChunkMapDistance::addPriorityTicket");
|
||||
+ long pair = coords.pair();
|
||||
+ PlayerChunk chunk = chunkMap.getUpdatingChunk(pair);
|
||||
+ if (chunk != null && chunk.isFullChunkReady()) {
|
||||
+ if (chunk != null && chunk.isFullChunkReady() && chunk.getTicketLevel() <= 33) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (chunk != null && chunk.getTicketLevel() > 33 && chunkMap.playerViewDistanceNoTickMap.getObjectsInRange(pair) != null) {
|
||||
+ Ticket<?> ticket = new Ticket<>(TicketType.PLAYER, 33, coords);
|
||||
+ addTicket(pair, ticket);
|
||||
+ }
|
||||
+ if (getChunkPriority(coords) >= priority) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ boolean success;
|
||||
+ if (!(success = updatePriorityTicket(coords, ticketType, priority))) {
|
||||
|
@ -280,7 +277,7 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..02d07d3ff5c3b824047402ff1f58aa33
|
|||
public <T> boolean addTicketAtLevel(TicketType<T> ticketType, ChunkCoordIntPair chunkcoordintpair, int level, T identifier) {
|
||||
return this.addTicket(chunkcoordintpair.pair(), new Ticket<>(ticketType, level, identifier));
|
||||
// CraftBukkit end
|
||||
@@ -384,24 +503,29 @@ public abstract class ChunkMapDistance {
|
||||
@@ -384,24 +500,26 @@ public abstract class ChunkMapDistance {
|
||||
Ticket<?> ticket = new Ticket<>(TicketType.PLAYER, 33, new ChunkCoordIntPair(i)); // Paper - no-tick view distance
|
||||
|
||||
if (flag1) {
|
||||
|
@ -289,12 +286,8 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..02d07d3ff5c3b824047402ff1f58aa33
|
|||
- if (this.c(this.c(i))) {
|
||||
+ // Paper start - smarter ticket delay based on frustum and distance
|
||||
+ scheduleChunkLoad(i, MinecraftServer.currentTick, j, (priority) -> {
|
||||
+ ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
|
||||
+ if (priority < 5 && this.c(this.c(i))) {
|
||||
+ // Skip throttle for near chunks
|
||||
+ ChunkMapDistance.this.addTicket(i, ticket);
|
||||
+ ChunkMapDistance.this.l.add(i);
|
||||
+ } else if (this.c(this.c(i))) { // Copy c(c()) stuff below
|
||||
+ //ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
|
||||
+ if (this.c(this.c(i))) { // Copy c(c()) stuff below
|
||||
+ // Paper end
|
||||
ChunkMapDistance.this.addTicket(i, ticket);
|
||||
ChunkMapDistance.this.l.add(i);
|
||||
|
@ -304,11 +297,13 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..02d07d3ff5c3b824047402ff1f58aa33
|
|||
}
|
||||
-
|
||||
- });
|
||||
}, i, () -> {
|
||||
- }, i, () -> {
|
||||
- return j;
|
||||
- }));
|
||||
+ return Math.min(PlayerChunkMap.GOLDEN_TICKET, (priority <= 6 ? 20 : 30) + priority); // Paper - delay new ticket adds to avoid spamming the queue
|
||||
+ })); }); // Paper
|
||||
+ //}, i, () -> {
|
||||
+ //return Math.min(PlayerChunkMap.GOLDEN_TICKET, (priority <= 6 ? 20 : 30) + priority); // Paper - delay new ticket adds to avoid spamming the queue
|
||||
+ //})); // Paper
|
||||
+ }); // Paper
|
||||
} else {
|
||||
ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
|
||||
ChunkMapDistance.this.m.execute(() -> {
|
||||
|
@ -317,7 +312,7 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..02d07d3ff5c3b824047402ff1f58aa33
|
|||
});
|
||||
}, i, true));
|
||||
}
|
||||
@@ -409,6 +533,99 @@ public abstract class ChunkMapDistance {
|
||||
@@ -409,6 +527,99 @@ public abstract class ChunkMapDistance {
|
||||
|
||||
}
|
||||
|
||||
|
@ -380,8 +375,8 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..02d07d3ff5c3b824047402ff1f58aa33
|
|||
+ }
|
||||
+ if (minDist > 4) {
|
||||
+ int desiredTimeDelayMax = isFront ?
|
||||
+ (minDist < 10 ? 10 : 15) : // Front
|
||||
+ (minDist < 10 ? 15 : 30); // Back
|
||||
+ (minDist < 10 ? 10 : 20) : // Front
|
||||
+ (minDist < 10 ? 20 : 40); // Back
|
||||
+ desireDelay += (desiredTimeDelayMax * 20) * (minDist / 32);
|
||||
+ }
|
||||
+ } else {
|
||||
|
@ -409,7 +404,7 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..02d07d3ff5c3b824047402ff1f58aa33
|
|||
+ if (delay <= 0) {
|
||||
+ task.accept((int) minDist);
|
||||
+ } else {
|
||||
+ MCUtil.scheduleTask((int) Math.min(delay, minDist >= 10 ? 40 : (minDist < 6 ? 10 : 20)), () -> scheduleChunkLoad(i, startTick, initialDistance, task), "Player Ticket Delayer");
|
||||
+ MCUtil.scheduleTask((int) Math.min(delay, minDist >= 10 ? 40 : (minDist < 6 ? 5 : 20)), () -> scheduleChunkLoad(i, startTick, initialDistance, task), "Player Ticket Delayer");
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
@ -418,7 +413,7 @@ index 7702fbefa598bce7e6a2d287f7ec36b78a62bff8..02d07d3ff5c3b824047402ff1f58aa33
|
|||
public void a() {
|
||||
super.a();
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
index 7a275bf3260f9fbefc41883c5ebdc1eb2196daf0..340d6e992786e8877243ccb472b462e88ec1e6fb 100644
|
||||
index 7a275bf3260f9fbefc41883c5ebdc1eb2196daf0..81a200ea4c533744890b6e19dd0d83f57351906c 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
@@ -432,6 +432,26 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
|
@ -466,7 +461,7 @@ index 7a275bf3260f9fbefc41883c5ebdc1eb2196daf0..340d6e992786e8877243ccb472b462e8
|
|||
} // Paper
|
||||
ichunkaccess = (IChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> {
|
||||
return ichunkaccess1;
|
||||
@@ -527,9 +551,10 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
@@ -527,13 +551,15 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
PlayerChunk.State currentChunkState = PlayerChunk.getChunkState(playerchunk.getTicketLevel());
|
||||
currentlyUnloading = (oldChunkState.isAtLeast(PlayerChunk.State.BORDER) && !currentChunkState.isAtLeast(PlayerChunk.State.BORDER));
|
||||
}
|
||||
|
@ -478,7 +473,12 @@ index 7a275bf3260f9fbefc41883c5ebdc1eb2196daf0..340d6e992786e8877243ccb472b462e8
|
|||
if (this.a(playerchunk, l)) {
|
||||
GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler();
|
||||
|
||||
@@ -542,8 +567,13 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
gameprofilerfiller.enter("chunkLoad");
|
||||
+ chunkMapDistance.delayDistanceManagerTick = false; // Paper - ensure this is never false
|
||||
this.tickDistanceManager();
|
||||
playerchunk = this.getChunk(k);
|
||||
gameprofilerfiller.exit();
|
||||
@@ -542,12 +568,17 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -494,7 +494,12 @@ index 7a275bf3260f9fbefc41883c5ebdc1eb2196daf0..340d6e992786e8877243ccb472b462e8
|
|||
}
|
||||
|
||||
private boolean a(@Nullable PlayerChunk playerchunk, int i) {
|
||||
@@ -593,7 +623,8 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
- return playerchunk == null || playerchunk.oldTicketLevel > i; // CraftBukkit using oldTicketLevel for isLoaded checks
|
||||
+ return playerchunk == null || playerchunk.getTicketLevel() > i; // CraftBukkit using oldTicketLevel for isLoaded checks - Paper - keep vanilla check
|
||||
}
|
||||
|
||||
public boolean isLoaded(int i, int j) {
|
||||
@@ -593,7 +624,8 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
return this.serverThreadQueue.executeNext();
|
||||
}
|
||||
|
||||
|
@ -559,7 +564,7 @@ index ce0bf608b71cf492fc31e89a360ecd83fa5c23a6..87d58002116f361d8255d79fc0dbd120
|
|||
chunkData.addProperty("queued-for-unload", chunkMap.unloadQueue.contains(playerChunk.location.pair()));
|
||||
chunkData.addProperty("status", status == null ? "unloaded" : status.toString());
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..04dcb79c6033f1dec62c5df49937a4ef067a2cb8 100644
|
||||
index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..bc5e380aa37101382c359f1c9a25803e09cd238c 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -26,8 +26,8 @@ public class PlayerChunk {
|
||||
|
@ -581,7 +586,7 @@ index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..04dcb79c6033f1dec62c5df49937a4ef
|
|||
|
||||
long lastAutoSaveTime; // Paper - incremental autosave
|
||||
long inactiveTimeStart; // Paper - incremental autosave
|
||||
@@ -67,6 +68,124 @@ public class PlayerChunk {
|
||||
@@ -67,6 +68,120 @@ public class PlayerChunk {
|
||||
return null;
|
||||
}
|
||||
// Paper end - no-tick view distance
|
||||
|
@ -606,11 +611,7 @@ index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..04dcb79c6033f1dec62c5df49937a4ef
|
|||
+ if (priorityBoost == ChunkMapDistance.URGENT_PRIORITY) {
|
||||
+ return 2; // Urgent - ticket level isn't always 31 so 33-30 = 3, but allow 1 more tasks to go below this for dependents
|
||||
+ }
|
||||
+ int basePriority = ticketLevel - priorityBoost;
|
||||
+ if (ticketLevel >= 33 && priorityBoost == 0 && (neighborPriority >= 34 || neighborPriorities.isEmpty())) {
|
||||
+ basePriority += 5;
|
||||
+ }
|
||||
+ return basePriority;
|
||||
+ return ticketLevel - priorityBoost;
|
||||
+ }
|
||||
+
|
||||
+ private int getNeighborsPriority() {
|
||||
|
@ -706,7 +707,7 @@ index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..04dcb79c6033f1dec62c5df49937a4ef
|
|||
|
||||
public PlayerChunk(ChunkCoordIntPair chunkcoordintpair, int i, LightEngine lightengine, PlayerChunk.c playerchunk_c, PlayerChunk.d playerchunk_d) {
|
||||
this.statusFutures = new AtomicReferenceArray(PlayerChunk.CHUNK_STATUSES.size());
|
||||
@@ -165,6 +284,15 @@ public class PlayerChunk {
|
||||
@@ -165,6 +280,15 @@ public class PlayerChunk {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -722,7 +723,7 @@ index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..04dcb79c6033f1dec62c5df49937a4ef
|
|||
// Paper end
|
||||
|
||||
public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> getStatusFutureUnchecked(ChunkStatus chunkstatus) {
|
||||
@@ -418,6 +546,7 @@ public class PlayerChunk {
|
||||
@@ -418,6 +542,7 @@ public class PlayerChunk {
|
||||
return this.n;
|
||||
}
|
||||
|
||||
|
@ -730,7 +731,7 @@ index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..04dcb79c6033f1dec62c5df49937a4ef
|
|||
private void d(int i) {
|
||||
this.n = i;
|
||||
}
|
||||
@@ -436,7 +565,7 @@ public class PlayerChunk {
|
||||
@@ -436,7 +561,7 @@ public class PlayerChunk {
|
||||
// CraftBukkit start
|
||||
// ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins.
|
||||
if (playerchunk_state.isAtLeast(PlayerChunk.State.BORDER) && !playerchunk_state1.isAtLeast(PlayerChunk.State.BORDER)) {
|
||||
|
@ -739,7 +740,7 @@ index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..04dcb79c6033f1dec62c5df49937a4ef
|
|||
Chunk chunk = (Chunk)either.left().orElse(null);
|
||||
if (chunk != null) {
|
||||
playerchunkmap.callbackExecutor.execute(() -> {
|
||||
@@ -501,12 +630,13 @@ public class PlayerChunk {
|
||||
@@ -501,12 +626,13 @@ public class PlayerChunk {
|
||||
if (!flag2 && flag3) {
|
||||
// Paper start - cache ticking ready status
|
||||
int expectCreateCount = ++this.fullChunkCreateCount;
|
||||
|
@ -754,7 +755,7 @@ index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..04dcb79c6033f1dec62c5df49937a4ef
|
|||
|
||||
|
||||
}
|
||||
@@ -531,7 +661,7 @@ public class PlayerChunk {
|
||||
@@ -531,7 +657,7 @@ public class PlayerChunk {
|
||||
|
||||
if (!flag4 && flag5) {
|
||||
// Paper start - cache ticking ready status
|
||||
|
@ -763,7 +764,7 @@ index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..04dcb79c6033f1dec62c5df49937a4ef
|
|||
if (either.left().isPresent()) {
|
||||
// note: Here is a very good place to add callbacks to logic waiting on this.
|
||||
Chunk tickingChunk = either.left().get();
|
||||
@@ -562,7 +692,7 @@ public class PlayerChunk {
|
||||
@@ -562,7 +688,7 @@ public class PlayerChunk {
|
||||
}
|
||||
|
||||
// Paper start - cache ticking ready status
|
||||
|
@ -772,7 +773,7 @@ index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..04dcb79c6033f1dec62c5df49937a4ef
|
|||
if (either.left().isPresent()) {
|
||||
// note: Here is a very good place to add callbacks to logic waiting on this.
|
||||
Chunk entityTickingChunk = either.left().get();
|
||||
@@ -581,13 +711,29 @@ public class PlayerChunk {
|
||||
@@ -581,13 +707,29 @@ public class PlayerChunk {
|
||||
this.entityTickingFuture.complete(PlayerChunk.UNLOADED_CHUNK); this.isEntityTickingReady = false; // Paper - cache chunk ticking stage
|
||||
this.entityTickingFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
|
||||
}
|
||||
|
@ -805,7 +806,7 @@ index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..04dcb79c6033f1dec62c5df49937a4ef
|
|||
Chunk chunk = (Chunk)either.left().orElse(null);
|
||||
if (chunk != null) {
|
||||
playerchunkmap.callbackExecutor.execute(() -> {
|
||||
@@ -669,6 +815,7 @@ public class PlayerChunk {
|
||||
@@ -669,6 +811,7 @@ public class PlayerChunk {
|
||||
|
||||
public interface c {
|
||||
|
||||
|
|
|
@ -38,10 +38,10 @@ index d051a54aa04326f84e211cd68ddd2bb209230770..bd7a92599b4182739aafef9eeaaf8665
|
|||
return this.j;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
index 340d6e992786e8877243ccb472b462e88ec1e6fb..451803d3f575b7fcd7ce0891bc1e2c86c2aa2832 100644
|
||||
index 81a200ea4c533744890b6e19dd0d83f57351906c..46d62aa414b340a14302e52bb882be08b58fa9a9 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
@@ -1089,7 +1089,7 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
@@ -1090,7 +1090,7 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
if (ChunkProviderServer.this.tickDistanceManager()) {
|
||||
return true;
|
||||
} else {
|
||||
|
@ -1332,10 +1332,10 @@ index 8cedfdd820cc02a76607b53e0b054fc74654f907..a9795394c9b17f9f0ce4c4f9c8f51a48
|
|||
private static final int nibbleBucketSizeMultiplier = Integer.getInteger("Paper.nibbleBucketSize", 3072);
|
||||
private static final int maxPoolSize = Integer.getInteger("Paper.maxNibblePoolSize", (int) Math.min(6, Math.max(1, Runtime.getRuntime().maxMemory() / 1024 / 1024 / 1024)) * (nibbleBucketSizeMultiplier * 8));
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index f8820f24075e7f42f67426fc9ecf5238f4499b72..0ef55c49235f8e024268b5411eeaf4ddc76c921d 100644
|
||||
index d04c8cdcc16ea7f0a49dc5720ddc8e47be0b634c..9c1be2e2d42701a96e8c40b377d13f5c0e92bf06 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -729,6 +729,7 @@ public class PlayerChunk {
|
||||
@@ -725,6 +725,7 @@ public class PlayerChunk {
|
||||
ioPriority = com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGH_PRIORITY;
|
||||
}
|
||||
chunkMap.world.asyncChunkTaskManager.raisePriority(location.x, location.z, ioPriority);
|
||||
|
|
Loading…
Reference in New Issue