Fix performance regression in loadChunk(x, z, false) (#2211)
Resolve a regression where calling loadChunk(x, z, false) would potentially double-load chunk data
This commit is contained in:
parent
31891d1916
commit
693102cce7
|
@ -1,4 +1,4 @@
|
||||||
From 27e5668efea88ccb9b7f77a1d7222b6b9f2ac65a Mon Sep 17 00:00:00 2001
|
From 23a4b689721fa3621f748f7f49390748eb82cf15 Mon Sep 17 00:00:00 2001
|
||||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||||
Date: Sat, 15 Jun 2019 08:54:33 -0700
|
Date: Sat, 15 Jun 2019 08:54:33 -0700
|
||||||
Subject: [PATCH] Fix World#isChunkGenerated calls
|
Subject: [PATCH] Fix World#isChunkGenerated calls
|
||||||
|
@ -232,10 +232,23 @@ index 2e14d84657..d610253b95 100644
|
||||||
}
|
}
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java
|
diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java
|
||||||
index 6f34d8aea0..d1323891fa 100644
|
index 6f34d8aea0..d2b3289450 100644
|
||||||
--- a/src/main/java/net/minecraft/server/RegionFileCache.java
|
--- a/src/main/java/net/minecraft/server/RegionFileCache.java
|
||||||
+++ b/src/main/java/net/minecraft/server/RegionFileCache.java
|
+++ b/src/main/java/net/minecraft/server/RegionFileCache.java
|
||||||
@@ -110,6 +110,7 @@ public abstract class RegionFileCache implements AutoCloseable {
|
@@ -47,6 +47,12 @@ public abstract class RegionFileCache implements AutoCloseable {
|
||||||
|
// Paper start
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Paper start
|
||||||
|
+ public RegionFile getRegionFileIfLoaded(ChunkCoordIntPair chunkcoordintpair) {
|
||||||
|
+ return this.cache.getAndMoveToFirst(ChunkCoordIntPair.pair(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ()));
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
+
|
||||||
|
public RegionFile getRegionFile(ChunkCoordIntPair chunkcoordintpair, boolean existingOnly) throws IOException { return this.a(chunkcoordintpair, existingOnly); } // Paper - OBFHELPER
|
||||||
|
private RegionFile a(ChunkCoordIntPair chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit
|
||||||
|
long i = ChunkCoordIntPair.pair(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ());
|
||||||
|
@@ -110,6 +116,7 @@ public abstract class RegionFileCache implements AutoCloseable {
|
||||||
try {
|
try {
|
||||||
NBTCompressedStreamTools.writeNBT(nbttagcompound, out);
|
NBTCompressedStreamTools.writeNBT(nbttagcompound, out);
|
||||||
out.close();
|
out.close();
|
||||||
|
@ -243,7 +256,7 @@ index 6f34d8aea0..d1323891fa 100644
|
||||||
regionfile.setOversized(chunkX, chunkZ, false);
|
regionfile.setOversized(chunkX, chunkZ, false);
|
||||||
} catch (RegionFile.ChunkTooLargeException ignored) {
|
} catch (RegionFile.ChunkTooLargeException ignored) {
|
||||||
printOversizedLog("ChunkTooLarge! Someone is trying to duplicate.", regionfile.file, chunkX, chunkZ);
|
printOversizedLog("ChunkTooLarge! Someone is trying to duplicate.", regionfile.file, chunkX, chunkZ);
|
||||||
@@ -127,6 +128,7 @@ public abstract class RegionFileCache implements AutoCloseable {
|
@@ -127,6 +134,7 @@ public abstract class RegionFileCache implements AutoCloseable {
|
||||||
if (SIZE_THRESHOLD == OVERZEALOUS_THRESHOLD) {
|
if (SIZE_THRESHOLD == OVERZEALOUS_THRESHOLD) {
|
||||||
resetFilterThresholds();
|
resetFilterThresholds();
|
||||||
}
|
}
|
||||||
|
@ -252,7 +265,7 @@ index 6f34d8aea0..d1323891fa 100644
|
||||||
printOversizedLog("ChunkTooLarge even after reduction. Trying in overzealous mode.", regionfile.file, chunkX, chunkZ);
|
printOversizedLog("ChunkTooLarge even after reduction. Trying in overzealous mode.", regionfile.file, chunkX, chunkZ);
|
||||||
// Eek, major fail. We have retry logic, so reduce threshholds and fall back
|
// Eek, major fail. We have retry logic, so reduce threshholds and fall back
|
||||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||||
index e0d89cc533..53d4f46d45 100644
|
index e0d89cc533..9bb1ad077a 100644
|
||||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||||
@@ -387,8 +387,20 @@ public class CraftWorld implements World {
|
@@ -387,8 +387,20 @@ public class CraftWorld implements World {
|
||||||
|
@ -277,7 +290,7 @@ index e0d89cc533..53d4f46d45 100644
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
@@ -500,20 +512,14 @@ public class CraftWorld implements World {
|
@@ -500,20 +512,24 @@ public class CraftWorld implements World {
|
||||||
@Override
|
@Override
|
||||||
public boolean loadChunk(int x, int z, boolean generate) {
|
public boolean loadChunk(int x, int z, boolean generate) {
|
||||||
org.spigotmc.AsyncCatcher.catchOp( "chunk load"); // Spigot
|
org.spigotmc.AsyncCatcher.catchOp( "chunk load"); // Spigot
|
||||||
|
@ -288,13 +301,22 @@ index e0d89cc533..53d4f46d45 100644
|
||||||
- // We then cycle through again to get the full chunk immediately, rather than after the ticket addition
|
- // We then cycle through again to get the full chunk immediately, rather than after the ticket addition
|
||||||
- chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, true);
|
- chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, true);
|
||||||
- }
|
- }
|
||||||
-
|
+ // Paper - Optimize this method
|
||||||
|
+ if (!generate) {
|
||||||
|
+ net.minecraft.server.RegionFile file = world.getChunkProvider().playerChunkMap.getRegionFileIfLoaded(new ChunkCoordIntPair(x, z));
|
||||||
|
+ if (file != null && file.getStatusIfCached(x, z) != ChunkStatus.FULL) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
|
||||||
- if (chunk instanceof net.minecraft.server.Chunk) {
|
- if (chunk instanceof net.minecraft.server.Chunk) {
|
||||||
- world.getChunkProvider().addTicket(TicketType.PLUGIN, new ChunkCoordIntPair(x, z), 1, Unit.INSTANCE);
|
- world.getChunkProvider().addTicket(TicketType.PLUGIN, new ChunkCoordIntPair(x, z), 1, Unit.INSTANCE);
|
||||||
- return true;
|
- return true;
|
||||||
+ // Paper - Optimize this method
|
+ IChunkAccess chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.EMPTY, true);
|
||||||
+ if (!generate && !isChunkGenerated(x, z)) {
|
+ if (!(chunk instanceof ProtoChunkExtension) && !(chunk instanceof net.minecraft.server.Chunk)) {
|
||||||
+ return false;
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ // fall through to load
|
||||||
|
+ // we do this so we do not re-read the chunk data on disk
|
||||||
}
|
}
|
||||||
-
|
-
|
||||||
- return false;
|
- return false;
|
||||||
|
@ -305,7 +327,7 @@ index e0d89cc533..53d4f46d45 100644
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2127,21 +2133,11 @@ public class CraftWorld implements World {
|
@@ -2127,21 +2143,20 @@ public class CraftWorld implements World {
|
||||||
|
|
||||||
// Paper start
|
// Paper start
|
||||||
private Chunk getChunkAtGen(int x, int z, boolean gen) {
|
private Chunk getChunkAtGen(int x, int z, boolean gen) {
|
||||||
|
@ -322,8 +344,17 @@ index e0d89cc533..53d4f46d45 100644
|
||||||
- if (chunk instanceof net.minecraft.server.Chunk) {
|
- if (chunk instanceof net.minecraft.server.Chunk) {
|
||||||
- return ((net.minecraft.server.Chunk)chunk).bukkitChunk;
|
- return ((net.minecraft.server.Chunk)chunk).bukkitChunk;
|
||||||
+ // Note: Copied from loadChunk()
|
+ // Note: Copied from loadChunk()
|
||||||
+ if (!gen && !isChunkGenerated(x, z)) {
|
+ if (!gen) {
|
||||||
+ return null;
|
+ net.minecraft.server.RegionFile file = world.getChunkProvider().playerChunkMap.getRegionFileIfLoaded(new ChunkCoordIntPair(x, z));
|
||||||
|
+ if (file != null && file.getStatusIfCached(x, z) != ChunkStatus.FULL) {
|
||||||
|
+ return null;
|
||||||
|
+ }
|
||||||
|
+ IChunkAccess chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.EMPTY, true);
|
||||||
|
+ if (!(chunk instanceof ProtoChunkExtension) && !(chunk instanceof net.minecraft.server.Chunk)) {
|
||||||
|
+ return null;
|
||||||
|
+ }
|
||||||
|
+ // fall through to load
|
||||||
|
+ // we do this so we do not re-read the chunk data on disk
|
||||||
}
|
}
|
||||||
-
|
-
|
||||||
- return null;
|
- return null;
|
||||||
|
|
Loading…
Reference in New Issue