mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-01 04:31:58 +01:00
Optimize Spare Chunk loads to be removed faster
this has technically been a longer standing problem, but if an async chunk loads after a chunk has been removed from the chunk map, it would be treated as any other spare chunk and kept loaded until Chunk GC kicks in. This fixes that, but also obsoletes ChunkGC in that anytime we load a spare chunk (a chunk outside of any players view distance), we will immediately mark it for unload. This should reduce the amount of spare chunks loaded on a server.
This commit is contained in:
parent
6135b37c05
commit
48b1b0aac5
5 changed files with 74 additions and 27 deletions
|
@ -1,4 +1,4 @@
|
||||||
From e46d08efd3f5e429c3d0cabb76bf8456bd03324b Mon Sep 17 00:00:00 2001
|
From a372872c9ea4562ff3b4cf6ab8b5853649d9db80 Mon Sep 17 00:00:00 2001
|
||||||
From: Aikar <aikar@aikar.co>
|
From: Aikar <aikar@aikar.co>
|
||||||
Date: Sat, 18 Jun 2016 23:22:12 -0400
|
Date: Sat, 18 Jun 2016 23:22:12 -0400
|
||||||
Subject: [PATCH] Delay Chunk Unloads based on Player Movement
|
Subject: [PATCH] Delay Chunk Unloads based on Player Movement
|
||||||
|
@ -16,6 +16,9 @@ before it actually unloads, which is maintained separately from ChunkGC.
|
||||||
This allows servers with smaller worlds who do less long distance exploring to stop
|
This allows servers with smaller worlds who do less long distance exploring to stop
|
||||||
wasting cpu cycles on saving/unloading/reloading chunks repeatedly.
|
wasting cpu cycles on saving/unloading/reloading chunks repeatedly.
|
||||||
|
|
||||||
|
This also makes the Chunk GC System useless, by auto scheduling unload as soon as
|
||||||
|
a spare chunk is added to the server thats outside of view distance.
|
||||||
|
|
||||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||||
index ff1a2046f6..0cd15c17e8 100644
|
index ff1a2046f6..0cd15c17e8 100644
|
||||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||||
|
@ -51,6 +54,26 @@ index 41d3aaa80b..824727ec66 100644
|
||||||
public final int locX;
|
public final int locX;
|
||||||
public final int locZ;
|
public final int locZ;
|
||||||
private boolean l; public boolean needsGapCheck() { return l; } // Paper - OBFHELPER
|
private boolean l; public boolean needsGapCheck() { return l; } // Paper - OBFHELPER
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/ChunkMap.java b/src/main/java/net/minecraft/server/ChunkMap.java
|
||||||
|
index df967ff07d..a3dc90fd2b 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/ChunkMap.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/ChunkMap.java
|
||||||
|
@@ -48,6 +48,15 @@ public class ChunkMap extends Long2ObjectOpenHashMap<Chunk> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ // Paper start - if this is a spare chunk (not part of any players view distance), go ahead and queue it for unload.
|
||||||
|
+ if (!((WorldServer)chunk.world).getPlayerChunkMap().isChunkInUse(chunk.locX, chunk.locZ)) {
|
||||||
|
+ if (chunk.world.paperConfig.delayChunkUnloadsBy > 0) {
|
||||||
|
+ chunk.scheduledForUnload = System.currentTimeMillis();
|
||||||
|
+ } else {
|
||||||
|
+ ((WorldServer) chunk.world).getChunkProviderServer().unload(chunk);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
chunk.world.timings.syncChunkLoadPostTimer.stopTiming(); // Paper
|
||||||
|
// CraftBukkit end
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||||
index 2d10f4aa37..719d5deb2c 100644
|
index 2d10f4aa37..719d5deb2c 100644
|
||||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||||
|
@ -76,10 +99,10 @@ index 2d10f4aa37..719d5deb2c 100644
|
||||||
this.chunkScheduler.a(booleansupplier);
|
this.chunkScheduler.a(booleansupplier);
|
||||||
}
|
}
|
||||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
index ac0e90eeca..3f4a8f21c0 100644
|
index ac0e90eeca..abf5a7554d 100644
|
||||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
@@ -33,8 +33,16 @@ public class PlayerChunk {
|
@@ -33,8 +33,22 @@ public class PlayerChunk {
|
||||||
public void run() {
|
public void run() {
|
||||||
loadInProgress = false;
|
loadInProgress = false;
|
||||||
PlayerChunk.this.chunk = PlayerChunk.this.playerChunkMap.getWorld().getChunkProviderServer().getChunkAt(location.x, location.z, true, true);
|
PlayerChunk.this.chunk = PlayerChunk.this.playerChunkMap.getWorld().getChunkProviderServer().getChunkAt(location.x, location.z, true, true);
|
||||||
|
@ -87,16 +110,22 @@ index ac0e90eeca..3f4a8f21c0 100644
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
+ // Paper start - delay chunk unloads
|
+ // Paper start - delay chunk unloads
|
||||||
+ public final void markChunkUsed() {
|
+ private void markChunkUsed() {
|
||||||
+ if (chunk != null && chunk.scheduledForUnload != null) {
|
+ if (chunk == null) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ if (!chunkHasPlayers) {
|
||||||
+ chunk.scheduledForUnload = null;
|
+ chunk.scheduledForUnload = null;
|
||||||
|
+ } else if (chunk.scheduledForUnload == null) {
|
||||||
|
+ chunk.scheduledForUnload = System.currentTimeMillis();
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
|
+ private boolean chunkHasPlayers = true;
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
|
||||||
public PlayerChunk(PlayerChunkMap playerchunkmap, int i, int j) {
|
public PlayerChunk(PlayerChunkMap playerchunkmap, int i, int j) {
|
||||||
@@ -44,6 +52,7 @@ public class PlayerChunk {
|
@@ -44,6 +58,7 @@ public class PlayerChunk {
|
||||||
|
|
||||||
chunkproviderserver.a(i, j);
|
chunkproviderserver.a(i, j);
|
||||||
this.chunk = chunkproviderserver.getChunkAt(i, j, true, false);
|
this.chunk = chunkproviderserver.getChunkAt(i, j, true, false);
|
||||||
|
@ -104,7 +133,25 @@ index ac0e90eeca..3f4a8f21c0 100644
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkCoordIntPair a() {
|
public ChunkCoordIntPair a() {
|
||||||
@@ -85,6 +94,7 @@ public class PlayerChunk {
|
@@ -56,6 +71,8 @@ public class PlayerChunk {
|
||||||
|
} else {
|
||||||
|
if (this.c.isEmpty()) {
|
||||||
|
this.i = this.playerChunkMap.getWorld().getTime();
|
||||||
|
+ chunkHasPlayers = false; // Paper - delay chunk unloads
|
||||||
|
+ markChunkUsed(); // Paper - delay chunk unloads
|
||||||
|
}
|
||||||
|
|
||||||
|
this.c.add(entityplayer);
|
||||||
|
@@ -74,6 +91,8 @@ public class PlayerChunk {
|
||||||
|
|
||||||
|
this.c.remove(entityplayer);
|
||||||
|
if (this.c.isEmpty()) {
|
||||||
|
+ chunkHasPlayers = true; // Paper - delay chunk unloads
|
||||||
|
+ markChunkUsed(); // Paper - delay chunk unloads
|
||||||
|
this.playerChunkMap.b(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -85,6 +104,7 @@ public class PlayerChunk {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
this.chunk = this.playerChunkMap.getWorld().getChunkProviderServer().getChunkAt(this.location.x, this.location.z, true, flag);
|
this.chunk = this.playerChunkMap.getWorld().getChunkProviderServer().getChunkAt(this.location.x, this.location.z, true, flag);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
From bc339909a375acc1fcb613875ca508e0ae4cfb80 Mon Sep 17 00:00:00 2001
|
From 4ea0d21a910e0b43daefd58d3f4c477d9ca703fa Mon Sep 17 00:00:00 2001
|
||||||
From: Aikar <aikar@aikar.co>
|
From: Aikar <aikar@aikar.co>
|
||||||
Date: Mon, 1 Jan 2018 16:10:24 -0500
|
Date: Mon, 1 Jan 2018 16:10:24 -0500
|
||||||
Subject: [PATCH] Configurable Max Chunk Gens per Tick
|
Subject: [PATCH] Configurable Max Chunk Gens per Tick
|
||||||
|
@ -33,7 +33,7 @@ index af69342e6c..ca7efc9175 100644
|
||||||
+ }
|
+ }
|
||||||
}
|
}
|
||||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
index 3f4a8f21c0..f8d8a44a88 100644
|
index abf5a7554d..84896d6f6b 100644
|
||||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
@@ -28,6 +28,7 @@ public class PlayerChunk {
|
@@ -28,6 +28,7 @@ public class PlayerChunk {
|
||||||
|
@ -44,7 +44,7 @@ index 3f4a8f21c0..f8d8a44a88 100644
|
||||||
private boolean loadInProgress = false;
|
private boolean loadInProgress = false;
|
||||||
private Runnable loadedRunnable = new Runnable() {
|
private Runnable loadedRunnable = new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -52,6 +53,7 @@ public class PlayerChunk {
|
@@ -58,6 +59,7 @@ public class PlayerChunk {
|
||||||
|
|
||||||
chunkproviderserver.a(i, j);
|
chunkproviderserver.a(i, j);
|
||||||
this.chunk = chunkproviderserver.getChunkAt(i, j, true, false);
|
this.chunk = chunkproviderserver.getChunkAt(i, j, true, false);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
From 7849249a2aa766c3b1d3e35b7cf3c5f21dd2a9a1 Mon Sep 17 00:00:00 2001
|
From 4d479efcce6177802b86638396126228f3c8351f Mon Sep 17 00:00:00 2001
|
||||||
From: stonar96 <minecraft.stonar96@gmail.com>
|
From: stonar96 <minecraft.stonar96@gmail.com>
|
||||||
Date: Mon, 20 Aug 2018 03:03:58 +0200
|
Date: Mon, 20 Aug 2018 03:03:58 +0200
|
||||||
Subject: [PATCH] Anti-Xray
|
Subject: [PATCH] Anti-Xray
|
||||||
|
@ -1418,10 +1418,10 @@ index 22a262bb60..40ec398eef 100644
|
||||||
if (flag) {
|
if (flag) {
|
||||||
packetdataserializer.writeBytes(chunksection.getSkyLightArray().asBytes());
|
packetdataserializer.writeBytes(chunksection.getSkyLightArray().asBytes());
|
||||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
index f8d8a44a88..e7d465fb8a 100644
|
index 84896d6f6b..2a889dc20a 100644
|
||||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
@@ -108,6 +108,8 @@ public class PlayerChunk {
|
@@ -118,6 +118,8 @@ public class PlayerChunk {
|
||||||
return false;
|
return false;
|
||||||
} else if (!this.chunk.isReady()) {
|
} else if (!this.chunk.isReady()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1430,7 +1430,7 @@ index f8d8a44a88..e7d465fb8a 100644
|
||||||
} else {
|
} else {
|
||||||
this.dirtyCount = 0;
|
this.dirtyCount = 0;
|
||||||
this.h = 0;
|
this.h = 0;
|
||||||
@@ -130,6 +132,7 @@ public class PlayerChunk {
|
@@ -140,6 +142,7 @@ public class PlayerChunk {
|
||||||
|
|
||||||
public void sendChunk(EntityPlayer entityplayer) {
|
public void sendChunk(EntityPlayer entityplayer) {
|
||||||
if (this.done) {
|
if (this.done) {
|
||||||
|
@ -1438,7 +1438,7 @@ index f8d8a44a88..e7d465fb8a 100644
|
||||||
entityplayer.playerConnection.sendPacket(new PacketPlayOutMapChunk(this.chunk, '\uffff'));
|
entityplayer.playerConnection.sendPacket(new PacketPlayOutMapChunk(this.chunk, '\uffff'));
|
||||||
this.playerChunkMap.getWorld().getTracker().a(entityplayer, this.chunk);
|
this.playerChunkMap.getWorld().getTracker().a(entityplayer, this.chunk);
|
||||||
}
|
}
|
||||||
@@ -194,6 +197,9 @@ public class PlayerChunk {
|
@@ -204,6 +207,9 @@ public class PlayerChunk {
|
||||||
this.a(this.playerChunkMap.getWorld().getTileEntity(blockposition));
|
this.a(this.playerChunkMap.getWorld().getTileEntity(blockposition));
|
||||||
}
|
}
|
||||||
} else if (this.dirtyCount == 64) {
|
} else if (this.dirtyCount == 64) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
From b75c9e7ccdb0bd7cedb1938ca328089e9bee5c51 Mon Sep 17 00:00:00 2001
|
From 34048ff608e60efadf17ad137dd11cf19ac7dc34 Mon Sep 17 00:00:00 2001
|
||||||
From: Aikar <aikar@aikar.co>
|
From: Aikar <aikar@aikar.co>
|
||||||
Date: Sat, 21 Jul 2018 16:55:04 -0400
|
Date: Sat, 21 Jul 2018 16:55:04 -0400
|
||||||
Subject: [PATCH] Async Chunk Loading and Generation
|
Subject: [PATCH] Async Chunk Loading and Generation
|
||||||
|
@ -1215,7 +1215,7 @@ index 0000000000..47d9ecdbf1
|
||||||
+
|
+
|
||||||
+}
|
+}
|
||||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
index e7d465fb8a..61de438fdf 100644
|
index 2a889dc20a..242691d89d 100644
|
||||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
@@ -30,13 +30,42 @@ public class PlayerChunk {
|
@@ -30,13 +30,42 @@ public class PlayerChunk {
|
||||||
|
@ -1265,9 +1265,9 @@ index e7d465fb8a..61de438fdf 100644
|
||||||
+ }
|
+ }
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
// Paper start - delay chunk unloads
|
// Paper start - delay chunk unloads
|
||||||
public final void markChunkUsed() {
|
private void markChunkUsed() {
|
||||||
if (chunk != null && chunk.scheduledForUnload != null) {
|
if (chunk == null) {
|
||||||
@@ -52,8 +81,8 @@ public class PlayerChunk {
|
@@ -58,8 +87,8 @@ public class PlayerChunk {
|
||||||
ChunkProviderServer chunkproviderserver = playerchunkmap.getWorld().getChunkProviderServer();
|
ChunkProviderServer chunkproviderserver = playerchunkmap.getWorld().getChunkProviderServer();
|
||||||
|
|
||||||
chunkproviderserver.a(i, j);
|
chunkproviderserver.a(i, j);
|
||||||
|
@ -1278,15 +1278,15 @@ index e7d465fb8a..61de438fdf 100644
|
||||||
markChunkUsed(); // Paper - delay chunk unloads
|
markChunkUsed(); // Paper - delay chunk unloads
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +97,7 @@ public class PlayerChunk {
|
@@ -76,6 +105,7 @@ public class PlayerChunk {
|
||||||
if (this.c.isEmpty()) {
|
chunkHasPlayers = false; // Paper - delay chunk unloads
|
||||||
this.i = this.playerChunkMap.getWorld().getTime();
|
markChunkUsed(); // Paper - delay chunk unloads
|
||||||
}
|
}
|
||||||
+ checkHighPriority(entityplayer); // Paper
|
+ checkHighPriority(entityplayer); // Paper
|
||||||
|
|
||||||
this.c.add(entityplayer);
|
this.c.add(entityplayer);
|
||||||
if (this.done) {
|
if (this.done) {
|
||||||
@@ -95,8 +125,13 @@ public class PlayerChunk {
|
@@ -105,8 +135,13 @@ public class PlayerChunk {
|
||||||
if (this.chunk != null) {
|
if (this.chunk != null) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
From 47c57748b767f78894eb5cc9ca5d073f114ee28a Mon Sep 17 00:00:00 2001
|
From 352ece97092f16a3e286a80a585c9da808c174dc Mon Sep 17 00:00:00 2001
|
||||||
From: Aikar <aikar@aikar.co>
|
From: Aikar <aikar@aikar.co>
|
||||||
Date: Sat, 29 Sep 2018 01:18:16 -0400
|
Date: Sat, 29 Sep 2018 01:18:16 -0400
|
||||||
Subject: [PATCH] Fix Sending Chunks to Client
|
Subject: [PATCH] Fix Sending Chunks to Client
|
||||||
|
@ -41,7 +41,7 @@ index 895eb60854..350479dc68 100644
|
||||||
}
|
}
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
index 61de438fdf..fca88c3018 100644
|
index 242691d89d..86f0fb3c2a 100644
|
||||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||||
@@ -23,7 +23,7 @@ public class PlayerChunk {
|
@@ -23,7 +23,7 @@ public class PlayerChunk {
|
||||||
|
@ -53,7 +53,7 @@ index 61de438fdf..fca88c3018 100644
|
||||||
|
|
||||||
// CraftBukkit start - add fields
|
// CraftBukkit start - add fields
|
||||||
// You know the drill, https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse
|
// You know the drill, https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse
|
||||||
@@ -136,6 +136,7 @@ public class PlayerChunk {
|
@@ -146,6 +146,7 @@ public class PlayerChunk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue