From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Shane Freeder 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 cf68c9105084d1823b5fc76b3f472a0f8ecd9568..d5b50a6a6816421c0443ae36213932b16ed5c797 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 ticketLevelTracker = new ChunkMapDistance.a(); private final ChunkMapDistance.b f = new ChunkMapDistance.b(8); private final ChunkMapDistance.c g = new ChunkMapDistance.c(33); - private final Set pendingChunkUpdates = Sets.newHashSet(); + // Paper start use a queue, but still keep unique requirement + public final java.util.Queue pendingChunkUpdates = new java.util.ArrayDeque() { + @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> j; private final Mailbox 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 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 ca41e420a1ab22f097dd0b98e156fd51434733d8..5efd611859648ed3c1bcda70728ea6106bd4bf4c 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> UNLOADED_CHUNK_FUTURE = CompletableFuture.completedFuture(PlayerChunk.UNLOADED_CHUNK); private static final List CHUNK_STATUSES = ChunkStatus.a(); private static final PlayerChunk.State[] CHUNK_STATES = PlayerChunk.State.values(); + boolean isUpdateQueued = false; // Paper private final AtomicReferenceArray>> statusFutures; private volatile CompletableFuture> fullChunkFuture; private int fullChunkCreateCount; private volatile boolean isFullChunkReady; // Paper - cache chunk ticking stage private volatile CompletableFuture> tickingFuture; private volatile boolean isTickingReady; // Paper - cache chunk ticking stage