2018-12-17 05:18:06 +00:00
From f5810f944e68391b4e1b8c35968b89a54f6ee177 Mon Sep 17 00:00:00 2001
2018-07-15 01:53:17 +00:00
From: Aikar <aikar@aikar.co>
Date: Thu, 27 Aug 2015 01:15:02 -0400
Subject: [PATCH] Optimize Chunk Access
getting a loaded chunk is one of the most hottest pieces of code in the game.
getChunkAt is called for the same chunk multiple times in a row, often from getType();
Optimize this look up by using a Last Access cache.
diff --git a/src/main/java/net/minecraft/server/ChunkMap.java b/src/main/java/net/minecraft/server/ChunkMap.java
2018-12-17 05:18:06 +00:00
index 732c8793e..8b3738c8f 100644
2018-07-15 01:53:17 +00:00
--- a/src/main/java/net/minecraft/server/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/ChunkMap.java
2018-08-27 04:15:12 +00:00
@@ -15,6 +15,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap<Chunk> {
2018-12-17 05:18:06 +00:00
public Chunk put(long i, Chunk chunk) {
2018-08-27 04:15:12 +00:00
chunk.world.timings.syncChunkLoadPostTimer.startTiming(); // Paper
+ lastChunkByPos = chunk; // Paper
Chunk chunk1 = (Chunk) super.put(i, chunk);
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i);
2018-10-18 02:47:27 +00:00
@@ -22,7 +23,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap<Chunk> {
for (int k = chunkcoordintpair.z - 1; k <= chunkcoordintpair.z + 1; ++k) {
if (j != chunkcoordintpair.x || k != chunkcoordintpair.z) {
long l = ChunkCoordIntPair.a(j, k);
- Chunk chunk2 = (Chunk) this.get(l);
+ Chunk chunk2 = (Chunk) super.get(l); // Paper - use super to avoid polluting last access cache
if (chunk2 != null) {
chunk.H();
@@ -40,7 +41,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap<Chunk> {
continue;
}
- Chunk neighbor = this.get(ChunkCoordIntPair.a(chunkcoordintpair.x + x, chunkcoordintpair.z + z));
+ Chunk neighbor = super.get(ChunkCoordIntPair.a(chunkcoordintpair.x + x, chunkcoordintpair.z + z)); // Paper - use super to avoid polluting last access cache
if (neighbor != null) {
neighbor.setNeighborLoaded(-x, -z);
chunk.setNeighborLoaded(x, z);
@@ -64,7 +65,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap<Chunk> {
for (int j = chunkcoordintpair.x - 1; j <= chunkcoordintpair.x + 1; ++j) {
for (int k = chunkcoordintpair.z - 1; k <= chunkcoordintpair.z + 1; ++k) {
if (j != chunkcoordintpair.x || k != chunkcoordintpair.z) {
- Chunk chunk1 = (Chunk) this.get(ChunkCoordIntPair.a(j, k));
+ Chunk chunk1 = (Chunk) super.get(ChunkCoordIntPair.a(j, k)); // Paper - use super to avoid polluting last access cache
if (chunk1 != null) {
chunk1.I();
2018-09-28 23:31:59 +00:00
@@ -73,8 +74,22 @@ public class ChunkMap extends Long2ObjectOpenHashMap<Chunk> {
2018-07-15 01:53:17 +00:00
}
}
+ // Paper start
+ if (lastChunkByPos != null && i == lastChunkByPos.chunkKey) {
+ lastChunkByPos = null;
+ }
return chunk;
}
2018-08-27 04:15:12 +00:00
+ private Chunk lastChunkByPos = null;
2018-07-15 01:53:17 +00:00
+
+ @Override
+ public Chunk get(long l) {
+ if (lastChunkByPos != null && l == lastChunkByPos.chunkKey) {
+ return lastChunkByPos;
+ }
2018-08-27 04:15:12 +00:00
+ return lastChunkByPos = super.get(l);
2018-07-15 01:53:17 +00:00
+ }
+ // Paper end
2018-12-17 05:18:06 +00:00
public Chunk remove(Object object) {
return this.remove((Long) object);
2018-08-27 04:15:12 +00:00
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
2018-12-08 10:09:55 +00:00
index 557aa5180..1d08ec37f 100644
2018-08-27 04:15:12 +00:00
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -78,15 +78,16 @@ public class ChunkProviderServer implements IChunkProvider {
Chunk chunk;
synchronized (this.chunkLoader) {
- if (this.lastChunk != null && this.lastChunk.getPos().x == i && this.lastChunk.getPos().z == j) {
+ // Paper start - remove vanilla lastChunk, we do it more accurately
+ /* if (this.lastChunk != null && this.lastChunk.locX == i && this.lastChunk.locZ == j) {
return this.lastChunk;
- }
+ }*/ // Paper end
long k = ChunkCoordIntPair.a(i, j);
chunk = (Chunk) this.chunks.get(k);
if (chunk != null) {
- this.lastChunk = chunk;
+ //this.lastChunk = chunk; // Paper remove vanilla lastChunk
return chunk;
}
@@ -198,7 +199,7 @@ public class ChunkProviderServer implements IChunkProvider {
}
this.chunks.put(k, chunk);
- this.lastChunk = chunk;
+ //this.lastChunk = chunk; // Paper
}
this.asyncTaskHandler.postToMainThread(chunk::addEntities);
2018-12-08 10:09:55 +00:00
@@ -345,7 +346,7 @@ public class ChunkProviderServer implements IChunkProvider {
2018-09-11 02:38:42 +00:00
this.saveChunk(chunk, true); // Spigot
}
this.chunks.remove(chunk.chunkKey);
- this.lastChunk = null;
+ // this.lastChunk = null; // Paper
2018-08-27 04:15:12 +00:00
}
return true;
}
2018-12-08 10:09:55 +00:00
@@ -381,6 +382,6 @@ public class ChunkProviderServer implements IChunkProvider {
2018-10-24 03:50:51 +00:00
}
public boolean isLoaded(int i, int j) {
- return this.chunks.containsKey(ChunkCoordIntPair.a(i, j));
+ return this.chunks.get(ChunkCoordIntPair.asLong(i, j)) != null; // Paper - use get for last access
}
}
2018-07-15 01:53:17 +00:00
--
2018-12-17 05:18:06 +00:00
2.20.0
2018-07-15 01:53:17 +00:00