aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0330-ChunkMapDistance-CME.patch
blob: 59ef83f7b1def35826fb4299c0c115fb41ae3338 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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/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<Void> 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<ChunkHolder> chunksToUpdateFutures = Sets.newHashSet();
+    // Paper start use a queue, but still keep unique requirement
+    public final java.util.Queue<ChunkHolder> pendingChunkUpdates = new java.util.ArrayDeque<ChunkHolder>() {
+        @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<ChunkTaskPriorityQueueSorter.Message<Runnable>> ticketThrottlerInput;
     final ProcessorHandle<ChunkTaskPriorityQueueSorter.Release> 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<ChunkHolder> 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);
                 }
 
             }