Paper/Spigot-Server-Patches/0375-ChunkMapDistance-CME.p...

75 lines
4.0 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Wed, 29 May 2019 04:01:22 +0100
Subject: [PATCH] ChunkMapDistance CME
diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
index ae661297774f51c8b61fc08ca43e13ba368d0021..83da76fdc495225b563cecbdb71422aec2b534f3 100644
--- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
+++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java
@@ -33,7 +33,16 @@ public abstract class ChunkMapDistance {
private final ChunkMapDistance.a e = new ChunkMapDistance.a();
private final ChunkMapDistance.b f = new ChunkMapDistance.b(8);
private final ChunkMapDistance.c g = new ChunkMapDistance.c(33);
- private final Set<PlayerChunk> pendingChunkUpdates = Sets.newHashSet();
+ // Paper start use a queue, but still keep unique requirement
+ public final java.util.Queue<PlayerChunk> pendingChunkUpdates = new java.util.ArrayDeque<PlayerChunk>() {
+ @Override
+ public boolean add(PlayerChunk o) {
+ if (o.isUpdateQueued) return true;
+ o.isUpdateQueued = true;
+ return super.add(o);
+ }
+ };
+ // Paper end
private final ChunkTaskQueueSorter i;
private final Mailbox<ChunkTaskQueueSorter.a<Runnable>> j;
private final Mailbox<ChunkTaskQueueSorter.b> k;
@@ -94,26 +103,14 @@ public abstract class ChunkMapDistance {
;
}
+ // Paper start
if (!this.pendingChunkUpdates.isEmpty()) {
- // CraftBukkit start
- // Iterate pending chunk updates with protection against concurrent modification exceptions
- java.util.Iterator<PlayerChunk> iter = this.pendingChunkUpdates.iterator();
- int expectedSize = this.pendingChunkUpdates.size();
- do {
- PlayerChunk playerchunk = iter.next();
- iter.remove();
- expectedSize--;
-
- playerchunk.a(playerchunkmap);
-
- // Reset iterator if set was modified using add()
- if (this.pendingChunkUpdates.size() != expectedSize) {
- expectedSize = this.pendingChunkUpdates.size();
- iter = this.pendingChunkUpdates.iterator();
- }
- } while (iter.hasNext());
- // CraftBukkit end
-
+ while(!this.pendingChunkUpdates.isEmpty()) {
+ PlayerChunk remove = this.pendingChunkUpdates.remove();
+ remove.isUpdateQueued = false;
+ remove.a(playerchunkmap);
+ }
+ // Paper end
return true;
} else {
if (!this.l.isEmpty()) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
index 6e9f402fb0faccc222b4289deb36e2d85a66eb7c..980044b9a81232e7d0eab8e4947db6ca1f845c1c 100644
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
@@ -18,6 +18,7 @@ public class PlayerChunk {
private static final CompletableFuture<Either<Chunk, PlayerChunk.Failure>> UNLOADED_CHUNK_FUTURE = CompletableFuture.completedFuture(PlayerChunk.UNLOADED_CHUNK);
private static final List<ChunkStatus> CHUNK_STATUSES = ChunkStatus.a();
private static final PlayerChunk.State[] CHUNK_STATES = PlayerChunk.State.values();
+ boolean isUpdateQueued = false; // Paper
private final AtomicReferenceArray<CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>>> statusFutures;
private volatile CompletableFuture<Either<Chunk, PlayerChunk.Failure>> fullChunkFuture; private int fullChunkCreateCount; private volatile boolean isFullChunkReady; // Paper - cache chunk ticking stage
private volatile CompletableFuture<Either<Chunk, PlayerChunk.Failure>> tickingFuture; private volatile boolean isTickingReady; // Paper - cache chunk ticking stage