geforkt von Mirrors/Paper
3fd3544a36
The lighting queue spreads out the processing of light updates across multiple ticks based on how much free time the server has left at the end of the tick.
115 Zeilen
5.2 KiB
Diff
115 Zeilen
5.2 KiB
Diff
From 03ee6c4a13460987076f859841235e5460bc2661 Mon Sep 17 00:00:00 2001
|
|
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/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
|
index 05417a7..c4b3461 100644
|
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
|
@@ -30,6 +30,7 @@ public class Chunk {
|
|
private boolean i;
|
|
public final World world;
|
|
public final int[] heightMap;
|
|
+ public final long chunkKey; // Paper
|
|
public final int locX;
|
|
public final int locZ;
|
|
private boolean l;
|
|
@@ -97,6 +98,7 @@ public class Chunk {
|
|
this.world = world;
|
|
this.locX = i;
|
|
this.locZ = j;
|
|
+ this.chunkKey = org.bukkit.craftbukkit.util.LongHash.toLong(this.locX, this.locZ); // Paper
|
|
this.heightMap = new int[256];
|
|
|
|
for (int k = 0; k < this.entitySlices.length; ++k) {
|
|
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
index f5a2580..f31ffe2 100644
|
|
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
@@ -24,7 +24,18 @@ public class ChunkProviderServer implements IChunkProvider {
|
|
public final ChunkUnloadQueue unloadQueue = new ChunkUnloadQueue(); // CraftBukkit - LongHashSet // Paper -> ChunkUnloadQueue
|
|
public final ChunkGenerator chunkGenerator; // CraftBukkit - public
|
|
private final IChunkLoader chunkLoader;
|
|
- public LongObjectHashMap<Chunk> chunks = new LongObjectHashMap<Chunk>(); // CraftBukkit
|
|
+ // Paper start
|
|
+ protected Chunk lastChunkByPos = null;
|
|
+ public LongObjectHashMap<Chunk> chunks = new LongObjectHashMap<Chunk>() {
|
|
+ @Override
|
|
+ public Chunk get(long key) {
|
|
+ if (lastChunkByPos != null && key == lastChunkByPos.chunkKey) {
|
|
+ return lastChunkByPos;
|
|
+ }
|
|
+ return lastChunkByPos = super.get(key);
|
|
+ }
|
|
+ }; // CraftBukkit
|
|
+ // Paper end
|
|
// private final LongHashMap<Chunk> chunks = new LongHashMap();
|
|
// private final List<Chunk> chunkList = Lists.newArrayList();
|
|
public final WorldServer world;
|
|
@@ -53,6 +64,7 @@ public class ChunkProviderServer implements IChunkProvider {
|
|
|
|
Chunk c = chunks.get(LongHash.toLong(i, j));
|
|
if (c != null) {
|
|
+ world.testResetChunkCache(c); // Paper
|
|
c.mustSave = true;
|
|
}
|
|
// CraftBukkit end
|
|
@@ -328,6 +340,7 @@ public class ChunkProviderServer implements IChunkProvider {
|
|
chunk.removeEntities();
|
|
this.saveChunk(chunk);
|
|
this.saveChunkNOP(chunk);
|
|
+ world.testResetChunkCache(chunk); // Paper
|
|
this.chunks.remove(chunkcoordinates); // CraftBukkit
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index 406bdaa..0419eb4 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -156,6 +156,12 @@ public abstract class World implements IBlockAccess {
|
|
public Chunk getChunkIfLoaded(BlockPosition blockposition) {
|
|
return this.chunkProvider.getLoadedChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4);
|
|
}
|
|
+
|
|
+ public void testResetChunkCache(Chunk chunk) {
|
|
+ if (chunk == ((ChunkProviderServer) chunkProvider).lastChunkByPos) {
|
|
+ ((ChunkProviderServer) chunkProvider).lastChunkByPos = null;
|
|
+ }
|
|
+ }
|
|
// Paper end
|
|
|
|
public Chunk getChunkIfLoaded(int x, int z) {
|
|
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
|
index 0e1cbfe..7e06fa9 100644
|
|
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
|
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
|
@@ -200,6 +200,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
|
// CraftBukkit end
|
|
|
|
public void doTick() {
|
|
+ ((ChunkProviderServer) chunkProvider).lastChunkByPos = null; // Paper
|
|
super.doTick();
|
|
if (this.getWorldData().isHardcore() && this.getDifficulty() != EnumDifficulty.HARD) {
|
|
this.getWorldData().setDifficulty(EnumDifficulty.HARD);
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
index caa5e62..c69e070 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
@@ -224,6 +224,7 @@ public class CraftWorld implements World {
|
|
|
|
world.getChunkProviderServer().unloadQueue.remove(x, z);
|
|
world.getChunkProviderServer().chunks.remove(LongHash.toLong(x, z));
|
|
+ world.testResetChunkCache(chunk); // Paper
|
|
|
|
// Update neighbor counts
|
|
for (int xx = -2; xx < 3; xx++) {
|
|
--
|
|
2.7.1.windows.2
|
|
|