Finish updating chunk system patch

Add in locking changes from folia, plus fix some diffs.
I'm sure it'll be error-free.
This commit is contained in:
Spottedleaf 2023-06-08 16:04:53 -07:00
parent dc11e08746
commit e031042af5
6 changed files with 3796 additions and 20229 deletions

View file

@ -127,6 +127,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- if (!this.player.noPhysics && !this.player.isSleeping() && (flag2 && worldserver.noCollision(this.player, axisalignedbb) || this.isPlayerCollidingWithAnythingNew(worldserver, axisalignedbb, d0, d1, d2))) {
+ // Paper start - optimise out extra getCubes
+ this.player.absMoveTo(d0, d1, d2, f, f1); // prevent desync by tping to the set position, dropped for unknown reasons by mojang
+ // Original for reference:
+ // boolean teleportBack = flag2 && worldserver.getCubes(this.player, axisalignedbb) || (didCollide && this.a((IWorldReader) worldserver, axisalignedbb));
+ boolean teleportBack = flag2; // violating this is always a fail

View file

@ -49,7 +49,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Paper start - distance maps
private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
+ public final io.papermc.paper.chunk.PlayerChunkLoader playerChunkManager = new io.papermc.paper.chunk.PlayerChunkLoader(this, this.pooledLinkedPlayerHashSets); // Paper - replace chunk loader
+ // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
+ // A note about the naming used here:
+ // Previously, mojang used a "spawn range" of 8 for controlling both ticking and

File diff suppressed because it is too large Load diff

View file

@ -1,28 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 8 Apr 2020 21:24:05 -0400
Subject: [PATCH] Increase Light Queue Size
Wiz mentioned that large WorldEdit operations cause light to run on
main thread. The queue was small, set to 5.. this bumps it to 20
but makes it configurable per-world.
The main risk of increasing this higher is during shutdown, some
queued light updates may be lost because mojang did not flush the
light engine on shutdown...
The queue size only puts a cap on max loss, doesn't solve that problem.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.executeModerately();
// CraftBukkit end
if (worldserver.getWorld().getKeepSpawnInMemory()) worldloadlistener.stop(); // Paper
- chunkproviderserver.getLightEngine().setTaskPerBatch(5);
+ chunkproviderserver.getLightEngine().setTaskPerBatch(worldserver.paperConfig().misc.lightQueueSize); // Paper - increase light queue size
// CraftBukkit start
// this.updateMobSpawningFlags();
worldserver.setSpawnSettings(this.isSpawningMonsters(), this.isSpawningAnimals());

File diff suppressed because it is too large Load diff

View file

@ -1,297 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 27 Apr 2020 04:05:38 -0700
Subject: [PATCH] Stop copy-on-write operations for updating light data
Causes huge memory allocations + gc issues
diff --git a/src/main/java/net/minecraft/world/level/lighting/BlockLightSectionStorage.java b/src/main/java/net/minecraft/world/level/lighting/BlockLightSectionStorage.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/lighting/BlockLightSectionStorage.java
+++ b/src/main/java/net/minecraft/world/level/lighting/BlockLightSectionStorage.java
@@ -0,0 +0,0 @@ import net.minecraft.world.level.chunk.LightChunkGetter;
public class BlockLightSectionStorage extends LayerLightSectionStorage<BlockLightSectionStorage.BlockDataLayerStorageMap> {
protected BlockLightSectionStorage(LightChunkGetter chunkProvider) {
- super(LightLayer.BLOCK, chunkProvider, new BlockLightSectionStorage.BlockDataLayerStorageMap(new Long2ObjectOpenHashMap<>()));
+ super(LightLayer.BLOCK, chunkProvider, new BlockLightSectionStorage.BlockDataLayerStorageMap(new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<>(), false)); // Paper - avoid copying light data
}
@Override
@@ -0,0 +0,0 @@ public class BlockLightSectionStorage extends LayerLightSectionStorage<BlockLigh
}
protected static final class BlockDataLayerStorageMap extends DataLayerStorageMap<BlockLightSectionStorage.BlockDataLayerStorageMap> {
- public BlockDataLayerStorageMap(Long2ObjectOpenHashMap<DataLayer> arrays) {
- super(arrays);
+ public BlockDataLayerStorageMap(com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<DataLayer> long2objectopenhashmap, boolean isVisible) { // Paper - avoid copying light data
+ super(long2objectopenhashmap, isVisible); // Paper - avoid copying light data
}
@Override
public BlockLightSectionStorage.BlockDataLayerStorageMap copy() {
- return new BlockLightSectionStorage.BlockDataLayerStorageMap(this.map.clone());
+ return new BlockDataLayerStorageMap(this.data, true); // Paper - avoid copying light data
}
}
}
diff --git a/src/main/java/net/minecraft/world/level/lighting/DataLayerStorageMap.java b/src/main/java/net/minecraft/world/level/lighting/DataLayerStorageMap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/lighting/DataLayerStorageMap.java
+++ b/src/main/java/net/minecraft/world/level/lighting/DataLayerStorageMap.java
@@ -0,0 +0,0 @@ public abstract class DataLayerStorageMap<M extends DataLayerStorageMap<M>> {
private final long[] lastSectionKeys = new long[2];
private final DataLayer[] lastSections = new DataLayer[2];
private boolean cacheEnabled;
- protected final Long2ObjectOpenHashMap<DataLayer> map;
+ protected final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<DataLayer> data; // Paper - avoid copying light data
+ protected final boolean isVisible; // Paper - avoid copying light data
+ java.util.function.Function<Long, DataLayer> lookup; // Paper - faster branchless lookup
- protected DataLayerStorageMap(Long2ObjectOpenHashMap<DataLayer> arrays) {
- this.map = arrays;
+ // Paper start - avoid copying light data
+ protected DataLayerStorageMap(com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<DataLayer> data, boolean isVisible) {
+ if (isVisible) {
+ data.performUpdatesLockMap();
+ }
+ this.data = data;
+ this.isVisible = isVisible;
+ if (isVisible) {
+ lookup = data::getVisibleAsync;
+ } else {
+ lookup = data::getUpdating;
+ }
+ // Paper end - avoid copying light data
this.clearCache();
this.cacheEnabled = true;
}
@@ -0,0 +0,0 @@ public abstract class DataLayerStorageMap<M extends DataLayerStorageMap<M>> {
public abstract M copy();
public void copyDataLayer(long pos) {
- this.map.put(pos, this.map.get(pos).copy());
+ if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
+ this.data.queueUpdate(pos, ((DataLayer) this.data.getUpdating(pos)).copy()); // Paper - avoid copying light data
this.clearCache();
}
public boolean hasLayer(long chunkPos) {
- return this.map.containsKey(chunkPos);
+ return lookup.apply(chunkPos) != null; // Paper - avoid copying light data
}
@Nullable
- public DataLayer getLayer(long chunkPos) {
+ public final DataLayer getLayer(long chunkPos) { // Paper - final
if (this.cacheEnabled) {
for(int i = 0; i < 2; ++i) {
if (chunkPos == this.lastSectionKeys[i]) {
@@ -0,0 +0,0 @@ public abstract class DataLayerStorageMap<M extends DataLayerStorageMap<M>> {
}
}
- DataLayer dataLayer = this.map.get(chunkPos);
+ DataLayer dataLayer = lookup.apply(chunkPos); // Paper - avoid copying light data
if (dataLayer == null) {
return null;
} else {
@@ -0,0 +0,0 @@ public abstract class DataLayerStorageMap<M extends DataLayerStorageMap<M>> {
@Nullable
public DataLayer removeLayer(long chunkPos) {
- return this.map.remove(chunkPos);
+ if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
+ return (DataLayer) this.data.queueRemove(chunkPos); // Paper - avoid copying light data
}
public void setLayer(long pos, DataLayer data) {
- this.map.put(pos, data);
+ if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
+ this.data.queueUpdate(pos, data); // Paper - avoid copying light data
}
public void clearCache() {
diff --git a/src/main/java/net/minecraft/world/level/lighting/LayerLightSectionStorage.java b/src/main/java/net/minecraft/world/level/lighting/LayerLightSectionStorage.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/lighting/LayerLightSectionStorage.java
+++ b/src/main/java/net/minecraft/world/level/lighting/LayerLightSectionStorage.java
@@ -0,0 +0,0 @@ public abstract class LayerLightSectionStorage<M extends DataLayerStorageMap<M>>
protected final LongSet dataSectionSet = new LongOpenHashSet();
protected final LongSet toMarkNoData = new LongOpenHashSet();
protected final LongSet toMarkData = new LongOpenHashSet();
- protected volatile M visibleSectionData;
+ protected volatile M e_visible; protected final Object visibleUpdateLock = new Object(); // Paper - diff on change, should be "visible" - force compile fail on usage change
protected final M updatingSectionData;
protected final LongSet changedSections = new LongOpenHashSet();
protected final LongSet sectionsAffectedByLightUpdates = new LongOpenHashSet();
@@ -0,0 +0,0 @@ public abstract class LayerLightSectionStorage<M extends DataLayerStorageMap<M>>
this.layer = lightType;
this.chunkSource = chunkProvider;
this.updatingSectionData = lightData;
- this.visibleSectionData = lightData.copy();
- this.visibleSectionData.disableCache();
+ this.e_visible = lightData.copy(); // Paper - avoid copying light dat
+ this.e_visible.disableCache(); // Paper - avoid copying light dat
}
protected boolean storingLightForSection(long sectionPos) {
@@ -0,0 +0,0 @@ public abstract class LayerLightSectionStorage<M extends DataLayerStorageMap<M>>
@Nullable
protected DataLayer getDataLayer(long sectionPos, boolean cached) {
- return this.getDataLayer((M)(cached ? this.updatingSectionData : this.visibleSectionData), sectionPos);
+ // Paper start - avoid copying light data
+ if (cached) {
+ return this.getDataLayer(this.updatingSectionData, sectionPos);
+ } else {
+ synchronized (this.visibleUpdateLock) {
+ return this.getDataLayer(this.e_visible, sectionPos);
+ }
+ }
+ // Paper end - avoid copying light data
}
@Nullable
@@ -0,0 +0,0 @@ public abstract class LayerLightSectionStorage<M extends DataLayerStorageMap<M>>
protected void swapSectionMap() {
if (!this.changedSections.isEmpty()) {
+ synchronized (this.visibleUpdateLock) { // Paper - avoid copying light data
M dataLayerStorageMap = this.updatingSectionData.copy();
dataLayerStorageMap.disableCache();
- this.visibleSectionData = dataLayerStorageMap;
+ this.e_visible = dataLayerStorageMap; // Paper - avoid copying light data
+ } // Paper - avoid copying light data
this.changedSections.clear();
}
diff --git a/src/main/java/net/minecraft/world/level/lighting/SkyLightSectionStorage.java b/src/main/java/net/minecraft/world/level/lighting/SkyLightSectionStorage.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/lighting/SkyLightSectionStorage.java
+++ b/src/main/java/net/minecraft/world/level/lighting/SkyLightSectionStorage.java
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
private volatile boolean hasSourceInconsistencies;
protected SkyLightSectionStorage(LightChunkGetter chunkProvider) {
- super(LightLayer.SKY, chunkProvider, new SkyLightSectionStorage.SkyDataLayerStorageMap(new Long2ObjectOpenHashMap<>(), new Long2IntOpenHashMap(), Integer.MAX_VALUE));
+ super(LightLayer.SKY, chunkProvider, new SkyLightSectionStorage.SkyDataLayerStorageMap(new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<>(), new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Int(), Integer.MAX_VALUE, false)); // Paper - avoid copying light data
}
@Override
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
protected int getLightValue(long blockPos, boolean cached) {
long l = SectionPos.blockToSection(blockPos);
int i = SectionPos.y(l);
- SkyLightSectionStorage.SkyDataLayerStorageMap skyDataLayerStorageMap = cached ? this.updatingSectionData : this.visibleSectionData;
- int j = skyDataLayerStorageMap.topSections.get(SectionPos.getZeroNode(l));
+ synchronized (this.visibleUpdateLock) { // Paper - avoid copying light data
+ SkyLightSectionStorage.SkyDataLayerStorageMap skyDataLayerStorageMap = (SkyLightSectionStorage.SkyDataLayerStorageMap) this.e_visible; // Paper - avoid copying light data - must be after lock acquire
+ int j = skyDataLayerStorageMap.otherData.getVisibleAsync(SectionPos.getZeroNode(l)); // Paper - avoid copying light data
if (j != skyDataLayerStorageMap.currentLowestY && i < j) {
DataLayer dataLayer = this.getDataLayer(skyDataLayerStorageMap, l);
if (dataLayer == null) {
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
} else {
return cached && !this.lightOnInSection(l) ? 0 : 15;
}
+ } // Paper - avoid copying light data
}
@Override
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
int i = SectionPos.y(sectionPos);
if ((this.updatingSectionData).currentLowestY > i) {
(this.updatingSectionData).currentLowestY = i;
- (this.updatingSectionData).topSections.defaultReturnValue((this.updatingSectionData).currentLowestY);
+ (this.updatingSectionData).otherData.queueDefaultReturnValue((this.updatingSectionData).currentLowestY); // Paper - avoid copying light data
}
long l = SectionPos.getZeroNode(sectionPos);
- int j = (this.updatingSectionData).topSections.get(l);
+ int j = (this.updatingSectionData).otherData.getUpdating(l); // Paper - avoid copying light data
if (j < i + 1) {
- (this.updatingSectionData).topSections.put(l, i + 1);
+ (this.updatingSectionData).otherData.queueUpdate(l, i + 1); // Paper - avoid copying light data
if (this.columnsWithSkySources.contains(l)) {
this.queueAddSource(sectionPos);
if (j > (this.updatingSectionData).currentLowestY) {
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
}
int i = SectionPos.y(sectionPos);
- if ((this.updatingSectionData).topSections.get(l) == i + 1) {
+ if ((this.updatingSectionData).otherData.getUpdating(l) == i + 1) { // Paper - avoid copying light data
long m;
for(m = sectionPos; !this.storingLightForSection(m) && this.hasSectionsBelow(i); m = SectionPos.offset(m, Direction.DOWN)) {
--i;
}
if (this.storingLightForSection(m)) {
- (this.updatingSectionData).topSections.put(l, i + 1);
+ (this.updatingSectionData).otherData.queueUpdate(l, i + 1); // Paper - avoid copying light data
if (bl) {
this.queueAddSource(m);
}
} else {
- (this.updatingSectionData).topSections.remove(l);
+ (this.updatingSectionData).otherData.queueRemove(l); // Paper - avoid copying light data
}
}
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
protected void enableLightSources(long columnPos, boolean enabled) {
this.runAllUpdates();
if (enabled && this.columnsWithSkySources.add(columnPos)) {
- int i = (this.updatingSectionData).topSections.get(columnPos);
+ int i = (this.updatingSectionData).otherData.getUpdating(columnPos); // Paper - avoid copying light data
if (i != (this.updatingSectionData).currentLowestY) {
long l = SectionPos.asLong(SectionPos.x(columnPos), i - 1, SectionPos.z(columnPos));
this.queueAddSource(l);
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
return dataLayer;
} else {
long l = SectionPos.offset(sectionPos, Direction.UP);
- int i = (this.updatingSectionData).topSections.get(SectionPos.getZeroNode(sectionPos));
+ int i = (this.updatingSectionData).otherData.getUpdating(SectionPos.getZeroNode(sectionPos)); // Paper - avoid copying light data
if (i != (this.updatingSectionData).currentLowestY && SectionPos.y(l) < i) {
DataLayer dataLayer2;
while((dataLayer2 = this.getDataLayer(l, true)) == null) {
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
protected boolean isAboveData(long sectionPos) {
long l = SectionPos.getZeroNode(sectionPos);
- int i = (this.updatingSectionData).topSections.get(l);
+ int i = (this.updatingSectionData).otherData.getUpdating(l); // Paper - avoid copying light data
return i == (this.updatingSectionData).currentLowestY || SectionPos.y(sectionPos) >= i;
}
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
protected static final class SkyDataLayerStorageMap extends DataLayerStorageMap<SkyLightSectionStorage.SkyDataLayerStorageMap> {
int currentLowestY;
- final Long2IntOpenHashMap topSections;
-
- public SkyDataLayerStorageMap(Long2ObjectOpenHashMap<DataLayer> arrays, Long2IntOpenHashMap columnToTopSection, int minSectionY) {
- super(arrays);
- this.topSections = columnToTopSection;
- columnToTopSection.defaultReturnValue(minSectionY);
+ private final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Int otherData; // Paper - avoid copying light data
+
+ // Paper start - avoid copying light data
+ public SkyDataLayerStorageMap(com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<DataLayer> arrays, com.destroystokyo.paper.util.map.QueuedChangesMapLong2Int columnToTopSection, int minSectionY, boolean isVisible) {
+ super(arrays, isVisible);
+ this.otherData = columnToTopSection;
+ otherData.queueDefaultReturnValue(minSectionY);
+ // Paper end
this.currentLowestY = minSectionY;
}
@Override
public SkyLightSectionStorage.SkyDataLayerStorageMap copy() {
- return new SkyLightSectionStorage.SkyDataLayerStorageMap(this.map.clone(), this.topSections.clone(), this.currentLowestY);
+ this.otherData.performUpdatesLockMap(); // Paper - avoid copying light data
+ return new SkyLightSectionStorage.SkyDataLayerStorageMap(this.data, this.otherData, this.currentLowestY, true); // Paper - avoid copying light data
}
}
}