Yatopia/patches/Tuinity/patches/server/0083-Do-not-copy-visible-ch...

211 lines
12 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 21 Mar 2021 11:22:10 -0700
Subject: [PATCH] Do not copy visible chunks
For servers with a lot of chunk holders, copying for each
tickDistanceManager call can take up quite a bit in
the function. I saw approximately 1/3rd of the function
on the copy.
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
index 848eb25ed0640db61a0f28bc26ddabd0444e9ed4..ec2b9995f1bf0f6cf029df7bfac526c2672acf3a 100644
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
@@ -407,7 +407,7 @@ public class PaperCommand extends Command {
int ticking = 0;
int entityTicking = 0;
- for (PlayerChunk chunk : world.getChunkProvider().playerChunkMap.updatingChunks.values()) {
+ for (PlayerChunk chunk : world.getChunkProvider().playerChunkMap.updatingChunks.getUpdatingMap().values()) { // Tuinity - change updating chunks map
if (chunk.getFullChunkIfCached() == null) {
continue;
}
diff --git a/src/main/java/net/minecraft/server/level/PlayerChunkMap.java b/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
index d7eede51f1c4ebbe8e00b16efd6331c87db53bb4..b28995ecfd7f45e6b6197be96c418aa0d05d3383 100644
--- a/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
@@ -116,8 +116,9 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
private static final Logger LOGGER = LogManager.getLogger();
public static final int GOLDEN_TICKET = 33 + ChunkStatus.b();
// Paper start - faster copying
- public final Long2ObjectLinkedOpenHashMap<PlayerChunk> updatingChunks = new com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<>(); // Paper - faster copying
- public final Long2ObjectLinkedOpenHashMap<PlayerChunk> visibleChunks = new ProtectedVisibleChunksMap(); // Paper - faster copying
+ // Tuinity start - Don't copy
+ public final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<PlayerChunk> updatingChunks = new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<>();
+ // Tuinity end - Don't copy
private class ProtectedVisibleChunksMap extends com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<PlayerChunk> {
@Override
@@ -140,8 +141,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
}
// Paper end
- public final com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<PlayerChunk> pendingVisibleChunks = new com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<PlayerChunk>(); // Paper - this is used if the visible chunks is updated while iterating only
- public transient com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<PlayerChunk> visibleChunksClone; // Paper - used for async access of visible chunks, clone and cache only when needed
+ // Tuinity - Don't copy
private final Long2ObjectLinkedOpenHashMap<PlayerChunk> pendingUnload;
public final LongSet loadedChunks; // Paper - private -> public
public final WorldServer world;
@@ -735,7 +735,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@Nullable
public PlayerChunk getUpdatingChunk(long i) { // Paper
- return (PlayerChunk) this.updatingChunks.get(i);
+ return this.updatingChunks.getUpdating(i); // Tuinity - Don't copy
}
// Paper start - remove cloning of visible chunks unless accessed as a collection async
@@ -743,47 +743,25 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
private boolean isIterating = false;
private boolean hasPendingVisibleUpdate = false;
public void forEachVisibleChunk(java.util.function.Consumer<PlayerChunk> consumer) {
- org.spigotmc.AsyncCatcher.catchOp("forEachVisibleChunk");
- boolean prev = isIterating;
- isIterating = true;
- try {
- for (PlayerChunk value : this.visibleChunks.values()) {
- consumer.accept(value);
- }
- } finally {
- this.isIterating = prev;
- if (!this.isIterating && this.hasPendingVisibleUpdate) {
- ((ProtectedVisibleChunksMap)this.visibleChunks).copyFrom(this.pendingVisibleChunks);
- this.pendingVisibleChunks.clear();
- this.hasPendingVisibleUpdate = false;
- }
- }
+ throw new UnsupportedOperationException(); // Tuinity - Don't copy
}
public Long2ObjectLinkedOpenHashMap<PlayerChunk> getVisibleChunks() {
- if (Thread.currentThread() == this.world.serverThread) {
- return this.visibleChunks;
- } else {
- synchronized (this.visibleChunks) {
- if (DEBUG_ASYNC_VISIBLE_CHUNKS) new Throwable("Async getVisibleChunks").printStackTrace();
- if (this.visibleChunksClone == null) {
- this.visibleChunksClone = this.hasPendingVisibleUpdate ? this.pendingVisibleChunks.clone() : ((ProtectedVisibleChunksMap)this.visibleChunks).clone();
- }
- return this.visibleChunksClone;
- }
+ // Tuinity start - Don't copy (except in rare cases)
+ synchronized (this.updatingChunks) {
+ return this.updatingChunks.getVisibleMap().clone();
}
+ // Tuinity end - Don't copy (except in rare cases)
}
// Paper end
@Nullable
public PlayerChunk getVisibleChunk(long i) { // Paper - protected -> public
- // Paper start - mt safe get
- if (Thread.currentThread() != this.world.serverThread) {
- synchronized (this.visibleChunks) {
- return (PlayerChunk) (this.hasPendingVisibleUpdate ? this.pendingVisibleChunks.get(i) : ((ProtectedVisibleChunksMap)this.visibleChunks).safeGet(i));
- }
+ // Tuinity start - Don't copy
+ if (Thread.currentThread() == this.world.serverThread) {
+ return this.updatingChunks.getVisible(i);
}
- return (PlayerChunk) (this.hasPendingVisibleUpdate ? this.pendingVisibleChunks.get(i) : ((ProtectedVisibleChunksMap)this.visibleChunks).safeGet(i));
- // Paper end
+ return this.updatingChunks.getVisibleAsync(i);
+ // Tuinity end - Don't copy
}
protected final IntSupplier getPrioritySupplier(long i) { return c(i); } // Paper - OBFHELPER
@@ -911,7 +889,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
this.getVillagePlace().dequeueUnload(playerchunk.location.pair()); // Tuinity - unload POI data
- this.updatingChunks.put(i, playerchunk);
+ this.updatingChunks.queueUpdate(i, playerchunk); // Tuinity - Don't copy
this.updatingChunksModified = true;
}
@@ -1064,7 +1042,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
while (longiterator.hasNext()) { // Spigot
long j = longiterator.nextLong();
longiterator.remove(); // Spigot
- PlayerChunk playerchunk = (PlayerChunk) this.updatingChunks.remove(j);
+ PlayerChunk playerchunk = this.updatingChunks.queueRemove(j); // Tuinity - Don't copy
if (playerchunk != null) {
this.pendingUnload.put(j, playerchunk);
@@ -1218,19 +1196,11 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
if (!this.updatingChunksModified) {
return false;
} else {
- // Paper start - stop cloning visibleChunks
- synchronized (this.visibleChunks) {
- if (isIterating) {
- hasPendingVisibleUpdate = true;
- this.pendingVisibleChunks.copyFrom((com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<PlayerChunk>)this.updatingChunks);
- } else {
- hasPendingVisibleUpdate = false;
- this.pendingVisibleChunks.clear();
- ((ProtectedVisibleChunksMap)this.visibleChunks).copyFrom((com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<PlayerChunk>)this.updatingChunks);
- this.visibleChunksClone = null;
- }
+ // Tuinity start - Don't copy
+ synchronized (this.updatingChunks) {
+ this.updatingChunks.performUpdates();
}
- // Paper end
+ // Tuinity end - Don't copy
this.updatingChunksModified = false;
return true;
@@ -1701,7 +1671,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
public int d() {
- return this.visibleChunks.size();
+ return this.updatingChunks.getVisibleMap().size(); // Tuinity - Don't copy
}
protected PlayerChunkMap.a e() {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 09cef73a92679e47c8670e4e4c1ba988878aee24..f7b17db87e351e8218d7865c3f9a0162892ca269 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -298,7 +298,7 @@ public class CraftWorld implements World {
public int getTileEntityCount() {
return net.minecraft.server.MCUtil.ensureMain(() -> {
// We don't use the full world tile entity list, so we must iterate chunks
- Long2ObjectLinkedOpenHashMap<PlayerChunk> chunks = world.getChunkProvider().playerChunkMap.visibleChunks;
+ Long2ObjectLinkedOpenHashMap<PlayerChunk> chunks = world.getChunkProvider().playerChunkMap.updatingChunks.getVisibleMap(); // Tuinity - change updating chunks map
int size = 0;
for (PlayerChunk playerchunk : chunks.values()) {
net.minecraft.world.level.chunk.Chunk chunk = playerchunk.getChunk();
@@ -317,7 +317,7 @@ public class CraftWorld implements World {
return net.minecraft.server.MCUtil.ensureMain(() -> {
int ret = 0;
- for (PlayerChunk chunkHolder : world.getChunkProvider().playerChunkMap.visibleChunks.values()) {
+ for (PlayerChunk chunkHolder : world.getChunkProvider().playerChunkMap.updatingChunks.getVisibleMap().values()) { // Tuinity - change updating chunks map
if (chunkHolder.getChunk() != null) {
++ret;
}
@@ -471,13 +471,16 @@ public class CraftWorld implements World {
public Chunk[] getLoadedChunks() {
// Paper start
if (Thread.currentThread() != world.getMinecraftWorld().serverThread) {
- synchronized (world.getChunkProvider().playerChunkMap.visibleChunks) {
- Long2ObjectLinkedOpenHashMap<PlayerChunk> chunks = world.getChunkProvider().playerChunkMap.visibleChunks;
- return chunks.values().stream().map(PlayerChunk::getFullChunk).filter(Objects::nonNull).map(net.minecraft.world.level.chunk.Chunk::getBukkitChunk).toArray(Chunk[]::new);
+ // Tuinity start - change updating chunks map
+ Long2ObjectLinkedOpenHashMap<PlayerChunk> chunks;
+ synchronized (world.getChunkProvider().playerChunkMap.updatingChunks) {
+ chunks = world.getChunkProvider().playerChunkMap.updatingChunks.getVisibleMap().clone();
}
+ return chunks.values().stream().map(PlayerChunk::getFullChunk).filter(Objects::nonNull).map(net.minecraft.world.level.chunk.Chunk::getBukkitChunk).toArray(Chunk[]::new);
+ // Tuinity end - change updating chunks map
}
// Paper end
- Long2ObjectLinkedOpenHashMap<PlayerChunk> chunks = world.getChunkProvider().playerChunkMap.visibleChunks;
+ Long2ObjectLinkedOpenHashMap<PlayerChunk> chunks = world.getChunkProvider().playerChunkMap.updatingChunks.getVisibleMap(); // Tuinity - change updating chunks map
return chunks.values().stream().map(PlayerChunk::getFullChunk).filter(Objects::nonNull).map(net.minecraft.world.level.chunk.Chunk::getBukkitChunk).toArray(Chunk[]::new);
}