mirror of https://github.com/YatopiaMC/Yatopia.git
211 lines
12 KiB
Diff
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);
|
|
}
|
|
|