Commits

md_5 authored 60f01ef304b
SPIGOT-1626 / MC-98994: Fix slow chunk performance

Please see https://bugs.mojang.com/browse/MC-98994 for full explanation.
No tags

nms-patches/ChunkProviderServer.patch

Modified
72 72 }
73 73
74 74 }
75 75
76 76 public void b() {
77 77 - Iterator iterator = this.chunkList.iterator();
78 78 + Iterator iterator = this.chunks.values().iterator(); // CraftBukkit
79 79
80 80 while (iterator.hasNext()) {
81 81 Chunk chunk = (Chunk) iterator.next();
82 -@@ -49,11 +70,15 @@
82 +@@ -49,11 +70,20 @@
83 83
84 84 }
85 85
86 86 + // CraftBukkit start - Add async variant, provide compatibility
87 ++ public Chunk getOrCreateChunkFast(int x, int z) {
88 ++ Chunk chunk = chunks.get(LongHash.toLong(x, z));
89 ++ return (chunk == null) ? getChunkAt(x, z) : chunk;
90 ++ }
91 ++
87 92 + public Chunk getChunkIfLoaded(int x, int z) {
88 93 + return chunks.get(LongHash.toLong(x, z));
89 94 + }
90 95 +
91 96 public Chunk getLoadedChunkAt(int i, int j) {
92 97 - long k = ChunkCoordIntPair.a(i, j);
93 98 - Chunk chunk = (Chunk) this.chunks.getEntry(k);
94 99 + Chunk chunk = chunks.get(LongHash.toLong(i, j)); // CraftBukkit
95 100
96 101 - this.unloadQueue.remove(Long.valueOf(k));
97 102 + this.unloadQueue.remove(i, j); // CraftBukkit
98 103 return chunk;
99 104 }
100 105
101 -@@ -61,20 +86,67 @@
106 +@@ -61,20 +91,67 @@
102 107 Chunk chunk = this.getLoadedChunkAt(i, j);
103 108
104 109 if (chunk == null) {
105 110 - chunk = this.loadChunk(i, j);
106 111 + // CraftBukkit start
107 112 + ChunkRegionLoader loader = null;
108 113 +
109 114 + if (this.chunkLoader instanceof ChunkRegionLoader) {
110 115 + loader = (ChunkRegionLoader) this.chunkLoader;
111 116 + }
161 166 + }
162 167 +
163 168 + public Chunk originalGetChunkAt(int i, int j) {
164 169 + this.unloadQueue.remove(i, j);
165 170 + Chunk chunk = this.chunks.get(LongHash.toLong(i, j));
166 171 + boolean newChunk = false;
167 172 + // CraftBukkit end
168 173
169 174 if (chunk == null) {
170 175 long k = ChunkCoordIntPair.a(i, j);
171 -@@ -92,11 +164,38 @@
176 +@@ -92,11 +169,38 @@
172 177 crashreportsystemdetails.a("Generator", (Object) this.chunkGenerator);
173 178 throw new ReportedException(crashreport);
174 179 }
175 180 + newChunk = true; // CraftBukkit
176 181 }
177 182
178 183 - this.chunks.put(k, chunk);
179 184 - this.chunkList.add(chunk);
180 185 + this.chunks.put(LongHash.toLong(i, j), chunk); // CraftBukkit
181 186 chunk.addEntities();
202 207 + if (neighbor != null) {
203 208 + neighbor.setNeighborLoaded(-x, -z);
204 209 + chunk.setNeighborLoaded(x, z);
205 210 + }
206 211 + }
207 212 + }
208 213 + // CraftBukkit end
209 214 chunk.loadNearby(this, this.chunkGenerator);
210 215 }
211 216
212 -@@ -142,10 +241,12 @@
217 +@@ -142,10 +246,12 @@
213 218
214 219 public boolean a(boolean flag) {
215 220 int i = 0;
216 221 - ArrayList arraylist = Lists.newArrayList(this.chunkList);
217 222
218 223 - for (int j = 0; j < arraylist.size(); ++j) {
219 224 - Chunk chunk = (Chunk) arraylist.get(j);
220 225 + // CraftBukkit start
221 226 + Iterator iterator = this.chunks.values().iterator();
222 227 + while (iterator.hasNext()) {
223 228 + Chunk chunk = (Chunk) iterator.next();
224 229 + // CraftBukkit end
225 230
226 231 if (flag) {
227 232 this.saveChunkNOP(chunk);
228 -@@ -170,22 +271,43 @@
233 +@@ -170,22 +276,43 @@
229 234
230 235 public boolean unloadChunks() {
231 236 if (!this.world.savingDisabled) {
232 237 - for (int i = 0; i < 100; ++i) {
233 238 - if (!this.unloadQueue.isEmpty()) {
234 239 - Long olong = (Long) this.unloadQueue.iterator().next();
235 240 - Chunk chunk = (Chunk) this.chunks.getEntry(olong.longValue());
236 241 + // CraftBukkit start
237 242 + Server server = this.world.getServer();
238 243 + for (int i = 0; i < 100 && !this.unloadQueue.isEmpty(); ++i) {
269 274 + chunk.setNeighborUnloaded(x, z);
270 275 + }
271 276 + }
272 277 + }
273 278 }
274 279 }
275 280 + // CraftBukkit end
276 281
277 282 this.chunkLoader.a();
278 283 }
279 -@@ -198,7 +320,8 @@
284 +@@ -198,7 +325,8 @@
280 285 }
281 286
282 287 public String getName() {
283 288 - return "ServerChunkCache: " + this.chunks.count() + " Drop: " + this.unloadQueue.size();
284 289 + // CraftBukkit - this.chunks.count() -> .size()
285 290 + return "ServerChunkCache: " + this.chunks.size() + " Drop: " + this.unloadQueue.size();
286 291 }
287 292
288 293 public List<BiomeBase.BiomeMeta> a(EnumCreatureType enumcreaturetype, BlockPosition blockposition) {
289 -@@ -210,10 +333,11 @@
294 +@@ -210,10 +338,11 @@
290 295 }
291 296
292 297 public int g() {
293 298 - return this.chunks.count();
294 299 + // CraftBukkit - this.chunks.count() -> this.chunks.size()
295 300 + return this.chunks.size();
296 301 }
297 302
298 303 public boolean e(int i, int j) {
299 304 - return this.chunks.contains(ChunkCoordIntPair.a(i, j));

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut