123 lines
6.5 KiB
Diff
123 lines
6.5 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/net/minecraft/server/ChunkSystem.java b/src/main/java/net/minecraft/server/ChunkSystem.java
|
||
|
index 83dc09f6526206690c474b50a7a6e71cefc93ab4..7f76c304f5eb3c2f27b348918588ab67b795b1ba 100644
|
||
|
--- a/src/main/java/net/minecraft/server/ChunkSystem.java
|
||
|
+++ b/src/main/java/net/minecraft/server/ChunkSystem.java
|
||
|
@@ -202,19 +202,24 @@ public final class ChunkSystem {
|
||
|
}
|
||
|
|
||
|
public static List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level) {
|
||
|
- return new ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values());
|
||
|
+ if (Bukkit.isPrimaryThread()) {
|
||
|
+ return level.chunkSource.chunkMap.updatingChunks.getVisibleValuesCopy();
|
||
|
+ }
|
||
|
+ synchronized (level.chunkSource.chunkMap.updatingChunks) {
|
||
|
+ return level.chunkSource.chunkMap.updatingChunks.getVisibleValuesCopy();
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
public static List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level) {
|
||
|
- return new ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values());
|
||
|
+ return level.chunkSource.chunkMap.updatingChunks.getUpdatingValuesCopy();
|
||
|
}
|
||
|
|
||
|
public static int getVisibleChunkHolderCount(final ServerLevel level) {
|
||
|
- return level.chunkSource.chunkMap.visibleChunkMap.size();
|
||
|
+ return level.chunkSource.chunkMap.updatingChunks.getVisibleMap().size();
|
||
|
}
|
||
|
|
||
|
public static int getUpdatingChunkHolderCount(final ServerLevel level) {
|
||
|
- return level.chunkSource.chunkMap.updatingChunkMap.size();
|
||
|
+ return level.chunkSource.chunkMap.updatingChunks.getUpdatingMap().size();
|
||
|
}
|
||
|
|
||
|
public static boolean hasAnyChunkHolders(final ServerLevel level) {
|
||
|
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||
|
index 2a9e5fb8164f79b0f9c1cb5497216e51f9df3454..ea27e6b1340a42c675bc68ed75f100569114be7a 100644
|
||
|
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||
|
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||
|
@@ -121,9 +121,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||
|
private static final int MIN_VIEW_DISTANCE = 3;
|
||
|
public static final int MAX_VIEW_DISTANCE = 33;
|
||
|
public static final int MAX_CHUNK_DISTANCE = 33 + ChunkStatus.maxDistance();
|
||
|
+ // Paper start - Don't copy
|
||
|
+ public final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<ChunkHolder> updatingChunks = new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<>();
|
||
|
+ // Paper end - Don't copy
|
||
|
public static final int FORCED_TICKET_LEVEL = 31;
|
||
|
- public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new Long2ObjectLinkedOpenHashMap();
|
||
|
- public volatile Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunkMap;
|
||
|
+ // Paper - Don't copy
|
||
|
private final Long2ObjectLinkedOpenHashMap<ChunkHolder> pendingUnloads;
|
||
|
public final LongSet entitiesInLevel;
|
||
|
public final ServerLevel level;
|
||
|
@@ -224,7 +226,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||
|
|
||
|
public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop<Runnable> mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier<DimensionDataStorage> persistentStateManagerFactory, int viewDistance, boolean dsync) {
|
||
|
super(session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync);
|
||
|
- this.visibleChunkMap = this.updatingChunkMap.clone();
|
||
|
+ // Paper - don't copy
|
||
|
this.pendingUnloads = new Long2ObjectLinkedOpenHashMap();
|
||
|
this.entitiesInLevel = new LongOpenHashSet();
|
||
|
this.toDrop = new LongOpenHashSet();
|
||
|
@@ -327,12 +329,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||
|
|
||
|
@Nullable
|
||
|
public ChunkHolder getUpdatingChunkIfPresent(long pos) {
|
||
|
- return (ChunkHolder) this.updatingChunkMap.get(pos);
|
||
|
+ return this.updatingChunks.getUpdating(pos); // Paper - Don't copy
|
||
|
}
|
||
|
|
||
|
@Nullable
|
||
|
public ChunkHolder getVisibleChunkIfPresent(long pos) {
|
||
|
- return (ChunkHolder) this.visibleChunkMap.get(pos);
|
||
|
+ // Paper start - Don't copy
|
||
|
+ if (Thread.currentThread() == this.level.thread) {
|
||
|
+ return this.updatingChunks.getVisible(pos);
|
||
|
+ }
|
||
|
+ return this.updatingChunks.getVisibleAsync(pos);
|
||
|
+ // Paper end - Don't copy
|
||
|
}
|
||
|
|
||
|
protected IntSupplier getChunkQueueLevel(long pos) {
|
||
|
@@ -515,7 +522,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||
|
// Paper start
|
||
|
holder.onChunkAdd();
|
||
|
// Paper end
|
||
|
- this.updatingChunkMap.put(pos, holder);
|
||
|
+ this.updatingChunks.queueUpdate(pos, holder); // Paper - Don't copy
|
||
|
this.modified = true;
|
||
|
}
|
||
|
|
||
|
@@ -592,7 +599,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||
|
|
||
|
for (int i = 0; longiterator.hasNext() && (shouldKeepTicking.getAsBoolean() || i < 200 || this.toDrop.size() > 2000); longiterator.remove()) {
|
||
|
long j = longiterator.nextLong();
|
||
|
- ChunkHolder playerchunk = (ChunkHolder) this.updatingChunkMap.remove(j);
|
||
|
+ ChunkHolder playerchunk = this.updatingChunks.queueRemove(j); // Paper - Don't copy
|
||
|
|
||
|
if (playerchunk != null) {
|
||
|
playerchunk.onChunkRemove(); // Paper
|
||
|
@@ -672,7 +679,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||
|
if (!this.modified) {
|
||
|
return false;
|
||
|
} else {
|
||
|
- this.visibleChunkMap = this.updatingChunkMap.clone();
|
||
|
+ // Paper start - Don't copy
|
||
|
+ synchronized (this.updatingChunks) {
|
||
|
+ this.updatingChunks.performUpdates();
|
||
|
+ }
|
||
|
+ // Paper end - Don't copy
|
||
|
+
|
||
|
this.modified = false;
|
||
|
return true;
|
||
|
}
|