From 60f01ef304badd4812cf17b3b39a3a53e4ee85d5 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Sat, 5 Mar 2016 18:50:38 +1100
Subject: [PATCH] SPIGOT-1626 / MC-98994: Fix slow chunk performance

Please see https://bugs.mojang.com/browse/MC-98994 for full explanation.
---
 nms-patches/ChunkProviderServer.patch | 19 ++++++++++++-------
 nms-patches/IChunkProvider.patch      |  9 +++++++++
 nms-patches/World.patch               |  7 ++++++-
 3 files changed, 27 insertions(+), 8 deletions(-)
 create mode 100644 nms-patches/IChunkProvider.patch

diff --git a/nms-patches/ChunkProviderServer.patch b/nms-patches/ChunkProviderServer.patch
index cb45aa3b06..59932d5159 100644
--- a/nms-patches/ChunkProviderServer.patch
+++ b/nms-patches/ChunkProviderServer.patch
@@ -79,11 +79,16 @@
  
          while (iterator.hasNext()) {
              Chunk chunk = (Chunk) iterator.next();
-@@ -49,11 +70,15 @@
+@@ -49,11 +70,20 @@
  
      }
  
 +    // CraftBukkit start - Add async variant, provide compatibility
++    public Chunk getOrCreateChunkFast(int x, int z) {
++        Chunk chunk = chunks.get(LongHash.toLong(x, z));
++        return (chunk == null) ? getChunkAt(x, z) : chunk;
++    }
++
 +    public Chunk getChunkIfLoaded(int x, int z) {
 +        return chunks.get(LongHash.toLong(x, z));
 +    }
@@ -98,7 +103,7 @@
          return chunk;
      }
  
-@@ -61,20 +86,67 @@
+@@ -61,20 +91,67 @@
          Chunk chunk = this.getLoadedChunkAt(i, j);
  
          if (chunk == null) {
@@ -168,7 +173,7 @@
  
          if (chunk == null) {
              long k = ChunkCoordIntPair.a(i, j);
-@@ -92,11 +164,38 @@
+@@ -92,11 +169,38 @@
                      crashreportsystemdetails.a("Generator", (Object) this.chunkGenerator);
                      throw new ReportedException(crashreport);
                  }
@@ -209,7 +214,7 @@
              chunk.loadNearby(this, this.chunkGenerator);
          }
  
-@@ -142,10 +241,12 @@
+@@ -142,10 +246,12 @@
  
      public boolean a(boolean flag) {
          int i = 0;
@@ -225,7 +230,7 @@
  
              if (flag) {
                  this.saveChunkNOP(chunk);
-@@ -170,22 +271,43 @@
+@@ -170,22 +276,43 @@
  
      public boolean unloadChunks() {
          if (!this.world.savingDisabled) {
@@ -276,7 +281,7 @@
  
              this.chunkLoader.a();
          }
-@@ -198,7 +320,8 @@
+@@ -198,7 +325,8 @@
      }
  
      public String getName() {
@@ -286,7 +291,7 @@
      }
  
      public List<BiomeBase.BiomeMeta> a(EnumCreatureType enumcreaturetype, BlockPosition blockposition) {
-@@ -210,10 +333,11 @@
+@@ -210,10 +338,11 @@
      }
  
      public int g() {
diff --git a/nms-patches/IChunkProvider.patch b/nms-patches/IChunkProvider.patch
new file mode 100644
index 0000000000..a0e6eeab92
--- /dev/null
+++ b/nms-patches/IChunkProvider.patch
@@ -0,0 +1,9 @@
+--- a/net/minecraft/server/IChunkProvider.java
++++ b/net/minecraft/server/IChunkProvider.java
+@@ -9,4 +9,6 @@
+     boolean unloadChunks();
+ 
+     String getName();
++
++    Chunk getOrCreateChunkFast(int x, int z); // CraftBukkit
+ }
diff --git a/nms-patches/World.patch b/nms-patches/World.patch
index 6238ecad4b..3f88db9e89 100644
--- a/nms-patches/World.patch
+++ b/nms-patches/World.patch
@@ -86,7 +86,12 @@
      }
  
      public World b() {
-@@ -197,6 +260,27 @@
+@@ -193,10 +256,31 @@
+     }
+ 
+     public Chunk getChunkAt(int i, int j) {
+-        return this.chunkProvider.getChunkAt(i, j);
++        return this.chunkProvider.getOrCreateChunkFast(i, j); // CraftBukkit
      }
  
      public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) {