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/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java index ffa3dc07ec566464ce10abe793de61efa9673fe9..d226247b93a2f1f7e039b0963d2e27b5dd11c15e 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java @@ -73,6 +73,7 @@ public class ChunkHolder { private boolean resendLight; private CompletableFuture pendingFullStateConfirmation; + boolean isUpdateQueued = false; // Paper private final ChunkMap chunkMap; // Paper public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) { diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java index 48bb57d3a431ea466425eb7da821c0aea900bd4c..45c7ebe67019cdbe88b6617a95d5c40d3a68286c 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java @@ -47,7 +47,16 @@ public abstract class DistanceManager { private final DistanceManager.ChunkTicketTracker ticketTracker = new DistanceManager.ChunkTicketTracker(); private final DistanceManager.FixedPlayerDistanceChunkTracker naturalSpawnChunkCounter = new DistanceManager.FixedPlayerDistanceChunkTracker(8); private final DistanceManager.PlayerTicketTracker playerTicketManager = new DistanceManager.PlayerTicketTracker(33); - final Set chunksToUpdateFutures = 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(ChunkHolder o) { + if (o.isUpdateQueued) return true; + o.isUpdateQueued = true; + return super.add(o); + } + }; + // Paper end final ChunkTaskPriorityQueueSorter ticketThrottler; final ProcessorHandle> ticketThrottlerInput; final ProcessorHandle ticketThrottlerReleaser; @@ -108,26 +117,14 @@ public abstract class DistanceManager { ; } - if (!this.chunksToUpdateFutures.isEmpty()) { - // CraftBukkit start - // Iterate pending chunk updates with protection against concurrent modification exceptions - java.util.Iterator iter = this.chunksToUpdateFutures.iterator(); - int expectedSize = this.chunksToUpdateFutures.size(); - do { - ChunkHolder playerchunk = iter.next(); - iter.remove(); - expectedSize--; - - playerchunk.updateFutures(playerchunkmap, this.mainThreadExecutor); - - // Reset iterator if set was modified using add() - if (this.chunksToUpdateFutures.size() != expectedSize) { - expectedSize = this.chunksToUpdateFutures.size(); - iter = this.chunksToUpdateFutures.iterator(); - } - } while (iter.hasNext()); - // CraftBukkit end - + // Paper start + if (!this.pendingChunkUpdates.isEmpty()) { + while(!this.pendingChunkUpdates.isEmpty()) { + ChunkHolder remove = this.pendingChunkUpdates.remove(); + remove.isUpdateQueued = false; + remove.updateFutures(playerchunkmap, this.mainThreadExecutor); + } + // Paper end return true; } else { if (!this.ticketsToRelease.isEmpty()) { @@ -385,7 +382,7 @@ public abstract class DistanceManager { if (k != level) { playerchunk = DistanceManager.this.updateChunkScheduling(id, level, playerchunk, k); if (playerchunk != null) { - DistanceManager.this.chunksToUpdateFutures.add(playerchunk); + DistanceManager.this.pendingChunkUpdates.add(playerchunk); } }