aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches/0078-Optimize-Chunk-Access.patch
blob: f411777afea77ebf9a52c94c2e54c43892aacae7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
From ce3c5c8ec8d6bf991d2d9231bf949ea2157e1f65 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/ChunkMap.java b/src/main/java/net/minecraft/server/ChunkMap.java
index 732c8793e..8b3738c8f 100644
--- a/src/main/java/net/minecraft/server/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/ChunkMap.java
@@ -15,6 +15,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap<Chunk> {
 
     public Chunk put(long i, Chunk chunk) {
         chunk.world.timings.syncChunkLoadPostTimer.startTiming(); // Paper
+        lastChunkByPos = chunk; // Paper
         Chunk chunk1 = (Chunk) super.put(i, chunk);
         ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i);
 
@@ -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();
@@ -73,8 +74,22 @@ public class ChunkMap extends Long2ObjectOpenHashMap<Chunk> {
             }
         }
 
+        // Paper start
+        if (lastChunkByPos != null && i == lastChunkByPos.chunkKey) {
+            lastChunkByPos = null;
+        }
         return chunk;
     }
+    private Chunk lastChunkByPos = null;
+
+    @Override
+    public Chunk get(long l) {
+        if (lastChunkByPos != null && l == lastChunkByPos.chunkKey) {
+            return lastChunkByPos;
+        }
+        return lastChunkByPos = super.get(l);
+    }
+    // Paper end
 
     public Chunk remove(Object object) {
         return this.remove((Long) object);
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 1ed7c7e2c..c54df4583 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -76,15 +76,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);
@@ -344,7 +345,7 @@ public class ChunkProviderServer implements IChunkProvider {
                 this.saveChunk(chunk, true); // Spigot
             }
             this.chunks.remove(chunk.chunkKey);
-            this.lastChunk = null;
+            // this.lastChunk = null; // Paper
         }
         return true;
     }
@@ -380,6 +381,6 @@ public class ChunkProviderServer implements IChunkProvider {
     }
 
     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
     }
 }
-- 
2.20.1