From a216c696e3b80efe8e525b57fd12f9d53d1c0c29 Mon Sep 17 00:00:00 2001 From: CraftBukkit/Spigot Date: Sat, 1 Feb 2014 17:42:43 -0600 Subject: [PATCH] Load all already generated chunks via async chunk system Currently we use the async chunk loading system only when players trigger chunk loading. If a chunk is loaded for any other reason it goes through a separate codepath. This means if a player has trigged a chunk load and before the chunk loads something else wants the same chunk we will load it twice and throw away the second result. With this change we instead use the sync processing feature of the AsynchronousExecutor to load the chunk which will pull it out of the queue if it was already queued to load. This means we only ever load a chunk once. Because chunk generation is not thread safe we still fallback to the vanilla chunk loading system if the chunk does not currently exist. By: Travis Watkins --- .../craftbukkit/chunkio/ChunkIOExecutor.java | 7 +++---- .../craftbukkit/chunkio/ChunkIOProvider.java | 20 +++++-------------- .../craftbukkit/chunkio/QueuedChunk.java | 12 ++++++----- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java b/paper-server/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java index 92fbc4f95d..afcf764b63 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java @@ -5,7 +5,6 @@ import net.minecraft.server.ChunkProviderServer; import net.minecraft.server.ChunkRegionLoader; import net.minecraft.server.World; import org.bukkit.craftbukkit.util.AsynchronousExecutor; -import org.bukkit.craftbukkit.util.LongHash; public class ChunkIOExecutor { static final int BASE_THREADS = 1; @@ -13,12 +12,12 @@ public class ChunkIOExecutor { private static final AsynchronousExecutor instance = new AsynchronousExecutor(new ChunkIOProvider(), BASE_THREADS); - public static void waitForChunkLoad(World world, int x, int z) { - instance.get(new QueuedChunk(LongHash.toLong(x, z), null, world, null)); + public static Chunk syncChunkLoad(World world, ChunkRegionLoader loader, ChunkProviderServer provider, int x, int z) { + return instance.getSkipQueue(new QueuedChunk(x, z, loader, world, provider)); } public static void queueChunkLoad(World world, ChunkRegionLoader loader, ChunkProviderServer provider, int x, int z, Runnable runnable) { - instance.add(new QueuedChunk(LongHash.toLong(x, z), loader, world, provider), runnable); + instance.add(new QueuedChunk(x, z, loader, world, provider), runnable); } public static void adjustPoolSize(int players) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java b/paper-server/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java index b9de12d88b..8feadd112a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java @@ -16,7 +16,7 @@ class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider