Skip to content

Commit

Permalink
Finish chunk tick iteration optimisation port from Moonrise
Browse files Browse the repository at this point in the history
  • Loading branch information
Spottedleaf committed Jul 17, 2024
1 parent 4efd24b commit b653276
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 403 deletions.
101 changes: 84 additions & 17 deletions patches/server/0988-Moonrise-optimisation-patches.patch
Original file line number Diff line number Diff line change
Expand Up @@ -25105,7 +25105,7 @@ index 3dc1daa3c6a04d3ff1a2353773b465fc380994a2..3575782f13a7f3c52e64dc5046803305
}
}
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9aec513f05b10e78579f79ccda6acf285f13222e 100644
index 60f678c26fb5144386d8697ddfd5b6d841563b6f..17fafa62f21e505f9f77cf486f7f766a404f7c31 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -46,7 +46,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
Expand All @@ -25117,7 +25117,7 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9aec513f05b10e78579f79ccda6acf28

public static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); // Paper
private static final List<ChunkStatus> CHUNK_STATUSES = ChunkStatus.getStatusList();
@@ -71,6 +71,61 @@ public class ServerChunkCache extends ChunkSource {
@@ -71,6 +71,62 @@ public class ServerChunkCache extends ChunkSource {
private final ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<net.minecraft.world.level.chunk.LevelChunk> fullChunks = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>();
long chunkFutureAwaitCounter;
// Paper end
Expand Down Expand Up @@ -25176,10 +25176,11 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9aec513f05b10e78579f79ccda6acf28
+ return load ? this.syncLoad(chunkX, chunkZ, toStatus) : null;
+ }
+ // Paper end - rewrite chunk system
+ private ServerChunkCache.ChunkAndHolder[] iterationCopy; // Paper - chunk tick iteration optimisations

public ServerChunkCache(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, int simulationDistance, boolean dsync, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier<DimensionDataStorage> persistentStateManagerFactory) {
this.level = world;
@@ -97,13 +152,7 @@ public class ServerChunkCache extends ChunkSource {
@@ -97,13 +153,7 @@ public class ServerChunkCache extends ChunkSource {
}
// CraftBukkit end
// Paper start
Expand All @@ -25194,7 +25195,7 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9aec513f05b10e78579f79ccda6acf28

@Nullable
public ChunkAccess getChunkAtImmediately(int x, int z) {
@@ -174,63 +223,25 @@ public class ServerChunkCache extends ChunkSource {
@@ -174,63 +224,25 @@ public class ServerChunkCache extends ChunkSource {
@Nullable
@Override
public ChunkAccess getChunk(int x, int z, ChunkStatus leastStatus, boolean create) {
Expand All @@ -25210,13 +25211,13 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9aec513f05b10e78579f79ccda6acf28
- }
- // Paper end - Perf: Optimise getChunkAt calls for loaded chunks
- ProfilerFiller gameprofilerfiller = this.level.getProfiler();
-
- gameprofilerfiller.incrementCounter("getChunk");
- long k = ChunkPos.asLong(x, z);
+ // Paper start - rewrite chunk system
+ if (leastStatus == ChunkStatus.FULL) {
+ final LevelChunk ret = this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(x, z));

- gameprofilerfiller.incrementCounter("getChunk");
- long k = ChunkPos.asLong(x, z);
-
- for (int l = 0; l < 4; ++l) {
- if (k == this.lastChunkPos[l] && leastStatus == this.lastChunkStatus[l]) {
- ChunkAccess ichunkaccess = this.lastChunk[l];
Expand Down Expand Up @@ -25268,7 +25269,7 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9aec513f05b10e78579f79ccda6acf28
}

private void clearCache() {
@@ -261,56 +272,59 @@ public class ServerChunkCache extends ChunkSource {
@@ -261,56 +273,59 @@ public class ServerChunkCache extends ChunkSource {
}

private CompletableFuture<ChunkResult<ChunkAccess>> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) {
Expand Down Expand Up @@ -25364,7 +25365,7 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9aec513f05b10e78579f79ccda6acf28
}

@Override
@@ -323,16 +337,7 @@ public class ServerChunkCache extends ChunkSource {
@@ -323,16 +338,7 @@ public class ServerChunkCache extends ChunkSource {
}

public boolean runDistanceManagerUpdates() { // Paper - public
Expand All @@ -25382,7 +25383,7 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9aec513f05b10e78579f79ccda6acf28
}

// Paper start
@@ -342,13 +347,14 @@ public class ServerChunkCache extends ChunkSource {
@@ -342,13 +348,14 @@ public class ServerChunkCache extends ChunkSource {
// Paper end

public boolean isPositionTicking(long pos) {
Expand All @@ -25401,7 +25402,7 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9aec513f05b10e78579f79ccda6acf28
try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings
this.chunkMap.saveAllChunks(flush);
} // Paper - Timings
@@ -361,12 +367,7 @@ public class ServerChunkCache extends ChunkSource {
@@ -361,12 +368,7 @@ public class ServerChunkCache extends ChunkSource {
}

public void close(boolean save) throws IOException {
Expand All @@ -25415,23 +25416,61 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9aec513f05b10e78579f79ccda6acf28
}

// CraftBukkit start - modelled on below
@@ -394,6 +395,7 @@ public class ServerChunkCache extends ChunkSource {
@@ -394,6 +396,7 @@ public class ServerChunkCache extends ChunkSource {
this.level.getProfiler().popPush("chunks");
if (tickChunks) {
this.level.timings.chunks.startTiming(); // Paper - timings
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getPlayerChunkLoader().tick(); // Paper - rewrite chunk system
this.tickChunks();
this.level.timings.chunks.stopTiming(); // Paper - timings
this.chunkMap.tick();
@@ -408,6 +410,7 @@ public class ServerChunkCache extends ChunkSource {
@@ -408,6 +411,7 @@ public class ServerChunkCache extends ChunkSource {
}

private void tickChunks() {
+ long chunksTicked = 0; // Paper - rewrite chunk system
long i = this.level.getGameTime();
long j = i - this.lastInhabitedUpdate;

@@ -460,14 +463,19 @@ public class ServerChunkCache extends ChunkSource {
@@ -417,18 +421,29 @@ public class ServerChunkCache extends ChunkSource {

gameprofilerfiller.push("pollingChunks");
gameprofilerfiller.push("filteringLoadedChunks");
- List<ServerChunkCache.ChunkAndHolder> list = Lists.newArrayListWithCapacity(this.chunkMap.size());
- Iterator iterator = this.chunkMap.getChunks().iterator();
- if (this.level.getServer().tickRateManager().runsNormally()) this.level.timings.chunkTicks.startTiming(); // Paper
+ // Paper start - chunk tick iteration optimisations
+ List<ServerChunkCache.ChunkAndHolder> list;
+ {
+ final ca.spottedleaf.moonrise.common.list.ReferenceList<net.minecraft.server.level.ServerChunkCache.ChunkAndHolder> tickingChunks =
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel) this.level).moonrise$getTickingChunks();

- while (iterator.hasNext()) {
- ChunkHolder playerchunk = (ChunkHolder) iterator.next();
- LevelChunk chunk = playerchunk.getTickingChunk();
+ final ServerChunkCache.ChunkAndHolder[] raw = tickingChunks.getRawDataUnchecked();
+ final int size = tickingChunks.size();

- if (chunk != null) {
- list.add(new ServerChunkCache.ChunkAndHolder(chunk, playerchunk));
+ if (this.iterationCopy == null || this.iterationCopy.length < size) {
+ this.iterationCopy = new ServerChunkCache.ChunkAndHolder[raw.length];
}
+ System.arraycopy(raw, 0, this.iterationCopy, 0, size);
+
+ list = it.unimi.dsi.fastutil.objects.ObjectArrayList.wrap(
+ this.iterationCopy, size
+ );
}
+ // Paper end - chunk tick iteration optimisations
+ Iterator iterator = null; // Paper - chunk tick iteration optimisations
+ if (this.level.getServer().tickRateManager().runsNormally()) this.level.timings.chunkTicks.startTiming(); // Paper
+
+ // Paper - chunk tick iteration optimisations

if (this.level.tickRateManager().runsNormally()) {
gameprofilerfiller.popPush("naturalSpawnCount");
@@ -460,14 +475,19 @@ public class ServerChunkCache extends ChunkSource {
LevelChunk chunk1 = chunkproviderserver_a.chunk;
ChunkPos chunkcoordintpair = chunk1.getPos();

Expand All @@ -25453,7 +25492,35 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9aec513f05b10e78579f79ccda6acf28
}
}
}
@@ -493,11 +501,12 @@ public class ServerChunkCache extends ChunkSource {
@@ -482,22 +502,35 @@ public class ServerChunkCache extends ChunkSource {
}

gameprofilerfiller.popPush("broadcast");
- list.forEach((chunkproviderserver_a1) -> {
- this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing
- chunkproviderserver_a1.holder.broadcastChanges(chunkproviderserver_a1.chunk);
- this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing
- });
+ // Paper start - chunk tick iteration optimisations
+ this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing
+ {
+ final it.unimi.dsi.fastutil.objects.ObjectArrayList<net.minecraft.server.level.ServerChunkCache.ChunkAndHolder> chunks = (it.unimi.dsi.fastutil.objects.ObjectArrayList<net.minecraft.server.level.ServerChunkCache.ChunkAndHolder>)list;
+ final ServerChunkCache.ChunkAndHolder[] raw = chunks.elements();
+ final int size = chunks.size();
+
+ Objects.checkFromToIndex(0, size, raw.length);
+ for (int idx = 0; idx < size; ++idx) {
+ final ServerChunkCache.ChunkAndHolder holder = raw[idx];
+ raw[idx] = null;
+
+ holder.holder().broadcastChanges(holder.chunk());
+ }
+ }
+ this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing
+ // Paper end - chunk tick iteration optimisations
gameprofilerfiller.pop();
gameprofilerfiller.pop();
}
}

private void getFullChunk(long pos, Consumer<LevelChunk> chunkConsumer) {
Expand All @@ -25470,7 +25537,7 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9aec513f05b10e78579f79ccda6acf28

}

@@ -591,6 +600,12 @@ public class ServerChunkCache extends ChunkSource {
@@ -591,6 +624,12 @@ public class ServerChunkCache extends ChunkSource {
this.chunkMap.setServerViewDistance(watchDistance);
}

Expand All @@ -25483,7 +25550,7 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9aec513f05b10e78579f79ccda6acf28
public void setSimulationDistance(int simulationDistance) {
this.distanceManager.updateSimulationDistance(simulationDistance);
}
@@ -669,21 +684,19 @@ public class ServerChunkCache extends ChunkSource {
@@ -669,21 +708,19 @@ public class ServerChunkCache extends ChunkSource {
@Override
// CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task
public boolean pollTask() {
Expand Down
12 changes: 10 additions & 2 deletions patches/server/0998-Optional-per-player-mob-spawns.patch
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ index edb36dee707433d4f9419aef6ac6cc0bec5f285e..c282566ee45d79b4fb3297989e054c80
// Paper end

diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 9aec513f05b10e78579f79ccda6acf285f13222e..96a03770d47c47e07615815bcc3d474d6cd7711b 100644
index 17fafa62f21e505f9f77cf486f7f766a404f7c31..2ed9a088d0fd56043d161909ce8e0df683a6413a 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -437,7 +437,19 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -449,14 +449,26 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
gameprofilerfiller.popPush("naturalSpawnCount");
this.level.timings.countNaturalMobs.startTiming(); // Paper - timings
int k = this.distanceManager.getNaturalSpawnChunkCount();
Expand All @@ -61,6 +61,14 @@ index 9aec513f05b10e78579f79ccda6acf285f13222e..96a03770d47c47e07615815bcc3d474d
this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings

this.lastSpawnState = spawnercreature_d;
gameprofilerfiller.popPush("spawnAndTick");
boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit

- Util.shuffle(list, this.level.random);
+ if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) Util.shuffle(list, this.level.random); // Paper - per player mob spawns - do not need this when per-player is enabled
// Paper start - PlayerNaturallySpawnCreaturesEvent
int chunkRange = level.spigotConfig.mobSpawnRange;
chunkRange = (chunkRange > level.spigotConfig.viewDistance) ? (byte) level.spigotConfig.viewDistance : chunkRange;
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index fd61e10fd3151bf8cc206a93d4ede22a7c681dbf..23ddb7735623e502eda2b7b3029c6597f4b0f9a0 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ index c282566ee45d79b4fb3297989e054c803873a294..dc64227e3b0d7855ef8870935aa437b7
}
// Paper end
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 96a03770d47c47e07615815bcc3d474d6cd7711b..5f195875564822f422127462fbbeea5df4a4e1cb 100644
index 2ed9a088d0fd56043d161909ce8e0df683a6413a..cdb9160244cc69acd36ac9afcfe109a15ab2ab58 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -443,7 +443,17 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -455,7 +455,17 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled
// re-set mob counts
for (ServerPlayer player : this.level.players) {
Expand Down
4 changes: 2 additions & 2 deletions patches/server/1036-Write-SavedData-IO-async.patch
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ Subject: [PATCH] Write SavedData IO async
Co-Authored-By: Shane Freeder <theboyetronic@gmail.com>

diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 5f195875564822f422127462fbbeea5df4a4e1cb..5149f7a5f0ee8620df582dcf26151e5842463cae 100644
index cdb9160244cc69acd36ac9afcfe109a15ab2ab58..8a0b00d645e4cf2ca96ec7e8ebc6ef726a0ab8b0 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -368,6 +368,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -369,6 +369,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon

public void close(boolean save) throws IOException {
((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.close(save, true); // Paper - rewrite chunk system
Expand Down
Loading

0 comments on commit b653276

Please sign in to comment.