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 5b8b9dabc6673b6f0a335a42d2ec71a583c410fb..74d674b2684b0db4aa6c183edc6091d53e9ee882 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java @@ -70,6 +70,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 19d3802becd353e130b785f8286e595e08dc5c5f..f0dac1f596911eb2109192ef16a619f8ae71d1f7 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java @@ -51,7 +51,16 @@ public abstract class DistanceManager { private final DistanceManager.FixedPlayerDistanceChunkTracker naturalSpawnChunkCounter = new DistanceManager.FixedPlayerDistanceChunkTracker(8); private final TickingTracker tickingTicketsTracker = new TickingTracker(); 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; @@ -126,26 +135,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(chunkStorage, 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(chunkStorage, this.mainThreadExecutor); + } + // Paper end return true; } else { if (!this.ticketsToRelease.isEmpty()) { @@ -434,7 +431,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); } }