mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-26 12:36:07 +01:00
Delay Chunk Unloads based on Player Movement
When players are moving in the world, doing things such as building or exploring, they will commonly go back and forth in a small area. This causes a ton of chunk load and unload activity on the edge chunks of their view distance. A simple back and forth movement in 6 blocks could spam a chunk to thrash a loading and unload cycle over and over again. This is very wasteful. This system introduces a delay of inactivity on a chunk before it actually unloads, which will be handled by the ticket expiry process. This allows servers with smaller worlds who do less long distance exploring to stop wasting cpu cycles on saving/unloading/reloading chunks repeatedly.
This commit is contained in:
parent
f0409edcd7
commit
9dfe1321d5
@ -0,0 +1,113 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Aikar <aikar@aikar.co>
|
||||||
|
Date: Sat, 18 Jun 2016 23:22:12 -0400
|
||||||
|
Subject: [PATCH] Delay Chunk Unloads based on Player Movement
|
||||||
|
|
||||||
|
When players are moving in the world, doing things such as building or exploring,
|
||||||
|
they will commonly go back and forth in a small area. This causes a ton of chunk load
|
||||||
|
and unload activity on the edge chunks of their view distance.
|
||||||
|
|
||||||
|
A simple back and forth movement in 6 blocks could spam a chunk to thrash a
|
||||||
|
loading and unload cycle over and over again.
|
||||||
|
|
||||||
|
This is very wasteful. This system introduces a delay of inactivity on a chunk
|
||||||
|
before it actually unloads, which will be handled by the ticket expiry process.
|
||||||
|
|
||||||
|
This allows servers with smaller worlds who do less long distance exploring to stop
|
||||||
|
wasting cpu cycles on saving/unloading/reloading chunks repeatedly.
|
||||||
|
|
||||||
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||||
|
index 5c8a946d5c895fc2622c7df656cc462c58104cf7..d64e996dde2c7665119c4bc1d907c40a8e3a63bc 100644
|
||||||
|
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||||
|
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||||
|
@@ -684,4 +684,13 @@ public class PaperWorldConfig {
|
||||||
|
private void viewDistance() {
|
||||||
|
this.noTickViewDistance = this.getInt("viewdistances.no-tick-view-distance", -1);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ public long delayChunkUnloadsBy;
|
||||||
|
+ private void delayChunkUnloadsBy() {
|
||||||
|
+ delayChunkUnloadsBy = PaperConfig.getSeconds(getString("delay-chunk-unloads-by", "10s"));
|
||||||
|
+ if (delayChunkUnloadsBy > 0) {
|
||||||
|
+ log("Delaying chunk unloads by " + delayChunkUnloadsBy + " seconds");
|
||||||
|
+ delayChunkUnloadsBy *= 20;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||||
|
index cbd7e82f22071f7453ce99f7a15d003653db227f..01e8b9bd3c3aded949edbae4c8bd1dc9d1637df2 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java
|
||||||
|
@@ -176,6 +176,27 @@ public abstract class ChunkMapDistance {
|
||||||
|
boolean removed = false; // CraftBukkit
|
||||||
|
if (arraysetsorted.remove(ticket)) {
|
||||||
|
removed = true; // CraftBukkit
|
||||||
|
+ // Paper start - delay chunk unloads for player tickets
|
||||||
|
+ long delayChunkUnloadsBy = chunkMap.world.paperConfig.delayChunkUnloadsBy;
|
||||||
|
+ if (ticket.getTicketType() == TicketType.PLAYER && delayChunkUnloadsBy > 0) {
|
||||||
|
+ boolean hasPlayer = false;
|
||||||
|
+ for (Ticket<?> ticket1 : arraysetsorted) {
|
||||||
|
+ if (ticket1.getTicketType() == TicketType.PLAYER) {
|
||||||
|
+ hasPlayer = true;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ PlayerChunk playerChunk = chunkMap.getUpdatingChunk(i);
|
||||||
|
+ if (!hasPlayer && playerChunk != null && playerChunk.isFullChunkReady()) {
|
||||||
|
+ Ticket<Long> delayUnload = new Ticket<Long>(TicketType.DELAY_UNLOAD, 33, i);
|
||||||
|
+ delayUnload.delayUnloadBy = delayChunkUnloadsBy;
|
||||||
|
+ delayUnload.setCurrentTick(this.currentTick);
|
||||||
|
+ arraysetsorted.remove(delayUnload);
|
||||||
|
+ // refresh ticket
|
||||||
|
+ arraysetsorted.add(delayUnload);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arraysetsorted.isEmpty()) {
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/Ticket.java b/src/main/java/net/minecraft/server/Ticket.java
|
||||||
|
index 0d6e0f2ddaa85c04e626980591e9a78ac27fb42d..c79aa4a80a8a2288f7a50466abd677f388360ba1 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/Ticket.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/Ticket.java
|
||||||
|
@@ -9,11 +9,13 @@ public final class Ticket<T> implements Comparable<Ticket<?>> {
|
||||||
|
public final T identifier; public final T getObjectReason() { return this.identifier; } // Paper - OBFHELPER
|
||||||
|
private long d; public final long getCreationTick() { return this.d; } // Paper - OBFHELPER
|
||||||
|
public int priority = 0; // Paper
|
||||||
|
+ public long delayUnloadBy; // Paper
|
||||||
|
|
||||||
|
protected Ticket(TicketType<T> tickettype, int i, T t0) {
|
||||||
|
this.a = tickettype;
|
||||||
|
this.b = i;
|
||||||
|
this.identifier = t0;
|
||||||
|
+ this.delayUnloadBy = tickettype.loadPeriod; // Paper
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(Ticket<?> ticket) {
|
||||||
|
@@ -57,12 +59,13 @@ public final class Ticket<T> implements Comparable<Ticket<?>> {
|
||||||
|
return this.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ protected void setCurrentTick(long i) { a(i); } // Paper - OBFHELPER
|
||||||
|
protected void a(long i) {
|
||||||
|
this.d = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean b(long i) {
|
||||||
|
- long j = this.a.b();
|
||||||
|
+ long j = delayUnloadBy; // Paper
|
||||||
|
|
||||||
|
return j != 0L && i - this.d > j;
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/TicketType.java b/src/main/java/net/minecraft/server/TicketType.java
|
||||||
|
index 24ec5d77ca7fdf12585c1bb7442554380f0c1918..02dce9e6da17eb78d80f83b798cc94ddfac734d7 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/TicketType.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/TicketType.java
|
||||||
|
@@ -25,6 +25,7 @@ public class TicketType<T> {
|
||||||
|
public static final TicketType<Long> ASYNC_LOAD = a("async_load", Long::compareTo); // Paper
|
||||||
|
public static final TicketType<ChunkCoordIntPair> PRIORITY = a("priority", Comparator.comparingLong(ChunkCoordIntPair::pair), 300); // Paper
|
||||||
|
public static final TicketType<ChunkCoordIntPair> URGENT = a("urgent", Comparator.comparingLong(ChunkCoordIntPair::pair), 300); // Paper
|
||||||
|
+ public static final TicketType<Long> DELAY_UNLOAD = a("delay_unload", Long::compareTo, 300); // Paper
|
||||||
|
|
||||||
|
public static <T> TicketType<T> a(String s, Comparator<T> comparator) {
|
||||||
|
return new TicketType<>(s, comparator, 0L);
|
Loading…
Reference in New Issue
Block a user