Unload leaked Cached Chunks

Due to some complexity in mojangs complicated chain of juggling
whether or not a chunk should be unloaded when the last ticket is
removed, many chunks are remaining around in the cache.

These chunks are never being targetted for unload because they are
vastly out of view distance range and have no reason to be looked at.

This is a huge issue for performance because we have to iterate these
chunks EVERY TICK... This is what's been leading to high SELF time in
Ticking Chunks timings/profiler results.

We will now detect these chunks in that iteration, and automatically
add it to the unload queue when the chunk is found without any tickets.
This commit is contained in:
Aikar 2020-05-25 11:12:22 -04:00
parent c9795e9221
commit 210a32f26f
No known key found for this signature in database
GPG key ID: 401ADFC9891FAAFE
30 changed files with 186 additions and 102 deletions

View file

@ -2382,7 +2382,7 @@ index c88a62f6b72a8851b95587bb49c898569d74e0c6..f8ac39e1b019b0918996f745d99f6ed0
this.d = i;
}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 55373cae078ddaf6c7c974abf59183698f669c24..b39ce329aa0b2e8da679a7b658f707f1da1f1a99 100644
index 55373cae078ddaf6c7c974abf59183698f669c24..9397b58f047c837f8a9146723e4cd9a4d6b787a7 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -25,7 +25,7 @@ import org.apache.logging.log4j.Logger;
@ -2412,7 +2412,7 @@ index 55373cae078ddaf6c7c974abf59183698f669c24..b39ce329aa0b2e8da679a7b658f707f1
this.i = chunkconverter;
HeightMap.Type[] aheightmap_type = HeightMap.Type.values();
int j = aheightmap_type.length;
@@ -108,6 +108,107 @@ public class Chunk implements IChunkAccess {
@@ -108,6 +108,110 @@ public class Chunk implements IChunkAccess {
public boolean needsDecoration;
// CraftBukkit end
@ -2473,6 +2473,9 @@ index 55373cae078ddaf6c7c974abf59183698f669c24..b39ce329aa0b2e8da679a7b658f707f1
+
+ }
+
+ public final boolean isAnyNeighborsLoaded() {
+ return neighbourChunksLoadedBitset != 0;
+ }
+ public final boolean areNeighboursLoaded(final int radius) {
+ return Chunk.areNeighboursLoaded(this.neighbourChunksLoadedBitset, radius);
+ }
@ -2520,7 +2523,7 @@ index 55373cae078ddaf6c7c974abf59183698f669c24..b39ce329aa0b2e8da679a7b658f707f1
public Chunk(World world, ProtoChunk protochunk) {
this(world, protochunk.getPos(), protochunk.getBiomeIndex(), protochunk.p(), protochunk.n(), protochunk.o(), protochunk.getInhabitedTime(), protochunk.getSections(), (Consumer) null);
Iterator iterator = protochunk.y().iterator();
@@ -213,6 +314,18 @@ public class Chunk implements IChunkAccess {
@@ -213,6 +317,18 @@ public class Chunk implements IChunkAccess {
}
}
@ -2539,7 +2542,7 @@ index 55373cae078ddaf6c7c974abf59183698f669c24..b39ce329aa0b2e8da679a7b658f707f1
@Override
public Fluid getFluid(BlockPosition blockposition) {
return this.a(blockposition.getX(), blockposition.getY(), blockposition.getZ());
@@ -352,6 +465,7 @@ public class Chunk implements IChunkAccess {
@@ -352,6 +468,7 @@ public class Chunk implements IChunkAccess {
entity.chunkX = this.loc.x;
entity.chunkY = k;
entity.chunkZ = this.loc.z;
@ -2547,7 +2550,7 @@ index 55373cae078ddaf6c7c974abf59183698f669c24..b39ce329aa0b2e8da679a7b658f707f1
this.entitySlices[k].add(entity);
}
@@ -374,6 +488,7 @@ public class Chunk implements IChunkAccess {
@@ -374,6 +491,7 @@ public class Chunk implements IChunkAccess {
}
this.entitySlices[i].remove(entity);
@ -2555,7 +2558,7 @@ index 55373cae078ddaf6c7c974abf59183698f669c24..b39ce329aa0b2e8da679a7b658f707f1
}
@Override
@@ -395,6 +510,7 @@ public class Chunk implements IChunkAccess {
@@ -395,6 +513,7 @@ public class Chunk implements IChunkAccess {
return this.a(blockposition, Chunk.EnumTileEntityState.CHECK);
}
@ -2563,7 +2566,7 @@ index 55373cae078ddaf6c7c974abf59183698f669c24..b39ce329aa0b2e8da679a7b658f707f1
@Nullable
public TileEntity a(BlockPosition blockposition, Chunk.EnumTileEntityState chunk_enumtileentitystate) {
// CraftBukkit start
@@ -506,7 +622,25 @@ public class Chunk implements IChunkAccess {
@@ -506,7 +625,25 @@ public class Chunk implements IChunkAccess {
// CraftBukkit start
public void loadCallback() {
@ -2589,7 +2592,7 @@ index 55373cae078ddaf6c7c974abf59183698f669c24..b39ce329aa0b2e8da679a7b658f707f1
if (server != null) {
/*
* If it's a new world, the first few chunks are generated inside
@@ -545,6 +679,22 @@ public class Chunk implements IChunkAccess {
@@ -545,6 +682,22 @@ public class Chunk implements IChunkAccess {
server.getPluginManager().callEvent(unloadEvent);
// note: saving can be prevented, but not forced if no saving is actually required
this.mustNotSave = !unloadEvent.isSaveChunk();

View file

@ -8,7 +8,7 @@ This enables us a fast reference to the entities current chunk instead
of having to look it up by hashmap lookups.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index b39ce329aa0b2e8da679a7b658f707f1da1f1a99..4d7dc714748a82470d00e787eeb3dc7ca08c656a 100644
index 9397b58f047c837f8a9146723e4cd9a4d6b787a7..e1ac0c479ebfa2da69575db2032dd1415c4a41a5 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -29,7 +29,7 @@ public class Chunk implements IChunkAccess {
@ -58,7 +58,7 @@ index b39ce329aa0b2e8da679a7b658f707f1da1f1a99..4d7dc714748a82470d00e787eeb3dc7c
this.l = Maps.newHashMap();
this.m = Maps.newHashMap();
this.n = new ShortList[16];
@@ -462,6 +487,7 @@ public class Chunk implements IChunkAccess {
@@ -465,6 +490,7 @@ public class Chunk implements IChunkAccess {
}
entity.inChunk = true;
@ -66,7 +66,7 @@ index b39ce329aa0b2e8da679a7b658f707f1da1f1a99..4d7dc714748a82470d00e787eeb3dc7c
entity.chunkX = this.loc.x;
entity.chunkY = k;
entity.chunkZ = this.loc.z;
@@ -474,6 +500,7 @@ public class Chunk implements IChunkAccess {
@@ -477,6 +503,7 @@ public class Chunk implements IChunkAccess {
((HeightMap) this.heightMap.get(heightmap_type)).a(along);
}
@ -74,7 +74,7 @@ index b39ce329aa0b2e8da679a7b658f707f1da1f1a99..4d7dc714748a82470d00e787eeb3dc7c
public void b(Entity entity) {
this.a(entity, entity.chunkY);
}
@@ -487,7 +514,12 @@ public class Chunk implements IChunkAccess {
@@ -490,7 +517,12 @@ public class Chunk implements IChunkAccess {
i = this.entitySlices.length - 1;
}

View file

@ -6,7 +6,7 @@ Subject: [PATCH] Store counts for each Entity/Block Entity Type
Opens door for future patches to optimize performance
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 4d7dc714748a82470d00e787eeb3dc7ca08c656a..a144f4ef5658359715ba493e6363c7e887d812d3 100644
index e1ac0c479ebfa2da69575db2032dd1415c4a41a5..f1b9b937e8ced0c718db463c94d716422113c396 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -56,15 +56,19 @@ public class Chunk implements IChunkAccess {
@ -37,7 +37,7 @@ index 4d7dc714748a82470d00e787eeb3dc7ca08c656a..a144f4ef5658359715ba493e6363c7e8
}
return removed;
}
@@ -486,6 +491,7 @@ public class Chunk implements IChunkAccess {
@@ -489,6 +494,7 @@ public class Chunk implements IChunkAccess {
k = this.entitySlices.length - 1;
}
@ -45,7 +45,7 @@ index 4d7dc714748a82470d00e787eeb3dc7ca08c656a..a144f4ef5658359715ba493e6363c7e8
entity.inChunk = true;
entity.setCurrentChunk(this); // Paper
entity.chunkX = this.loc.x;
@@ -519,6 +525,7 @@ public class Chunk implements IChunkAccess {
@@ -522,6 +528,7 @@ public class Chunk implements IChunkAccess {
if (!this.entitySlices[i].remove(entity)) {
return;
}

View file

@ -343,10 +343,10 @@ index cd72a9c84569592f9c82708a17388e594648d19d..5de881371a485957fd8fadc7540a2b54
private final float frictionFactor;
private final float f;
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index a144f4ef5658359715ba493e6363c7e887d812d3..352bb787fddca85a1aa06d263211841a2a6fada7 100644
index f1b9b937e8ced0c718db463c94d716422113c396..43dc791191cdf2aa3e5cb2768c25e6be4b2cf6b1 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -689,6 +689,7 @@ public class Chunk implements IChunkAccess {
@@ -692,6 +692,7 @@ public class Chunk implements IChunkAccess {
server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(this.bukkitChunk, this.needsDecoration));
if (this.needsDecoration) {
@ -354,7 +354,7 @@ index a144f4ef5658359715ba493e6363c7e887d812d3..352bb787fddca85a1aa06d263211841a
this.needsDecoration = false;
java.util.Random random = new java.util.Random();
random.setSeed(world.getSeed());
@@ -708,6 +709,7 @@ public class Chunk implements IChunkAccess {
@@ -711,6 +712,7 @@ public class Chunk implements IChunkAccess {
}
}
server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk));

View file

@ -5,10 +5,10 @@ Subject: [PATCH] Remove invalid mob spawner tile entities
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 352bb787fddca85a1aa06d263211841a2a6fada7..687e609cab33aaea62784fb338ce70606a831217 100644
index 43dc791191cdf2aa3e5cb2768c25e6be4b2cf6b1..ef779879e33c2f64c325afd3cd411032fb0d63f9 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -604,6 +604,10 @@ public class Chunk implements IChunkAccess {
@@ -607,6 +607,10 @@ public class Chunk implements IChunkAccess {
}
// CraftBukkit start

View file

@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..f699ce18ca044f813e194ef2786b7ea8
+ }
+}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 687e609cab33aaea62784fb338ce70606a831217..8f3eee5ea812320af02e1bb6d2378fbbbef62e3c 100644
index ef779879e33c2f64c325afd3cd411032fb0d63f9..b85e21202eb8bb9446989aa1d6889eed784762a4 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -1,5 +1,6 @@
@ -59,7 +59,7 @@ index 687e609cab33aaea62784fb338ce70606a831217..8f3eee5ea812320af02e1bb6d2378fbb
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
@@ -609,10 +610,15 @@ public class Chunk implements IChunkAccess {
@@ -612,10 +613,15 @@ public class Chunk implements IChunkAccess {
this.tileEntities.remove(blockposition);
// Paper end
} else {

View file

@ -31,10 +31,10 @@ index a3b5793e4824718c8bf3d0a4f963de0ca94a738e..71089442c189336fc0061852a6615817
public BaseBlockPosition(int i, int j, int k) {
this.a = i;
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 8f3eee5ea812320af02e1bb6d2378fbbbef62e3c..4b162a768ed7f0a319309430b081943bf9c39b9c 100644
index b85e21202eb8bb9446989aa1d6889eed784762a4..324cd78f8c896d300d1e74acde3db6a81dab2b0d 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -304,12 +304,24 @@ public class Chunk implements IChunkAccess {
@@ -307,12 +307,24 @@ public class Chunk implements IChunkAccess {
return this.sections;
}

View file

@ -30,10 +30,10 @@ index 6ef0e1399e9ff260712db1a044068c125b1316d3..5872e6b171416686b11678ac9f65706b
+ }
}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 4b162a768ed7f0a319309430b081943bf9c39b9c..6694d0e36c0a3dc86c5b4e6fc1f132395ac36fc0 100644
index 324cd78f8c896d300d1e74acde3db6a81dab2b0d..f5298a2fa911a18a5d390666c92155dd618666c5 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -970,7 +970,7 @@ public class Chunk implements IChunkAccess {
@@ -973,7 +973,7 @@ public class Chunk implements IChunkAccess {
@Override
public long getInhabitedTime() {

View file

@ -19,10 +19,10 @@ index 8cf3076f4e0d8d7e81158881c763f89ebda7e678..721eceeffc843da8b9da1ccc2d07f3bc
+ }
}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 6694d0e36c0a3dc86c5b4e6fc1f132395ac36fc0..87d68a3e2161798b7496542093f09b2b739ad45b 100644
index f5298a2fa911a18a5d390666c92155dd618666c5..23bce1c192f6c354b7fe8858515be5f98a8fe6c3 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -630,6 +630,12 @@ public class Chunk implements IChunkAccess {
@@ -633,6 +633,12 @@ public class Chunk implements IChunkAccess {
"Chunk coordinates: " + (this.loc.x * 16) + "," + (this.loc.z * 16));
e.printStackTrace();
ServerInternalException.reportInternalException(e);

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Mark chunk dirty anytime entities change to guarantee it
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 87d68a3e2161798b7496542093f09b2b739ad45b..6a40dddf467d741300b86075577f9af4840b5f06 100644
index 23bce1c192f6c354b7fe8858515be5f98a8fe6c3..0b62004422108e126d80a879c203fab0455e1451 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -512,6 +512,7 @@ public class Chunk implements IChunkAccess {
@@ -515,6 +515,7 @@ public class Chunk implements IChunkAccess {
entity.chunkZ = this.loc.z;
this.entities.add(entity); // Paper - per chunk entity list
this.entitySlices[k].add(entity);
@ -17,7 +17,7 @@ index 87d68a3e2161798b7496542093f09b2b739ad45b..6a40dddf467d741300b86075577f9af4
}
@Override
@@ -539,6 +540,7 @@ public class Chunk implements IChunkAccess {
@@ -542,6 +543,7 @@ public class Chunk implements IChunkAccess {
return;
}
entityCounts.decrement(entity.getMinecraftKeyString());

View file

@ -9,10 +9,10 @@ This should hopefully avoid duplicate entities ever being created
if the entity was to end up in 2 different chunk slices
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 6a40dddf467d741300b86075577f9af4840b5f06..0afa8a7ebd8dbdfaac362d66b687e787bc040dee 100644
index 0b62004422108e126d80a879c203fab0455e1451..4e7f3065694c8811d5c98bcda64ae32b220e0d7a 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -503,6 +503,25 @@ public class Chunk implements IChunkAccess {
@@ -506,6 +506,25 @@ public class Chunk implements IChunkAccess {
if (k >= this.entitySlices.length) {
k = this.entitySlices.length - 1;
}
@ -38,7 +38,7 @@ index 6a40dddf467d741300b86075577f9af4840b5f06..0afa8a7ebd8dbdfaac362d66b687e787
if (!entity.inChunk || entity.getCurrentChunk() != this) entityCounts.increment(entity.getMinecraftKeyString()); // Paper
entity.inChunk = true;
@@ -512,6 +531,7 @@ public class Chunk implements IChunkAccess {
@@ -515,6 +534,7 @@ public class Chunk implements IChunkAccess {
entity.chunkZ = this.loc.z;
this.entities.add(entity); // Paper - per chunk entity list
this.entitySlices[k].add(entity);
@ -46,7 +46,7 @@ index 6a40dddf467d741300b86075577f9af4840b5f06..0afa8a7ebd8dbdfaac362d66b687e787
this.markDirty(); // Paper
}
@@ -536,6 +556,10 @@ public class Chunk implements IChunkAccess {
@@ -539,6 +559,10 @@ public class Chunk implements IChunkAccess {
// Paper start
if (entity.currentChunk != null && entity.currentChunk.get() == this) entity.setCurrentChunk(null);
@ -58,7 +58,7 @@ index 6a40dddf467d741300b86075577f9af4840b5f06..0afa8a7ebd8dbdfaac362d66b687e787
return;
}
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index a0379c6a779a5507993827a1402f2acb02eca658..838aa7da699e969e9f067cea54e092959aa83143 100644
index 653e6d9a1640bedf08aaa5b436ac93e4cb1cb5b7..84d36ea84e25a701af22900af6cd3099adf6cd54 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -71,6 +71,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke

View file

@ -23,10 +23,10 @@ index b839769ceae8932bb121a0b96fde1e7d129a1f63..5acad8e44f024d3ddf5ef4fd320460ac
MutablePair<Integer, Map<ChunkCoordIntPair, Integer>> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap()));
ChunkCoordIntPair chunk = new ChunkCoordIntPair(e.getChunkX(), e.getChunkZ());
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 0afa8a7ebd8dbdfaac362d66b687e787bc040dee..8e9ddca049f837ed1c5fc4aa9fd6a6858dbc36be 100644
index 4e7f3065694c8811d5c98bcda64ae32b220e0d7a..5453eaae5b165a76b55a085d70081159b8e66770 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -810,6 +810,7 @@ public class Chunk implements IChunkAccess {
@@ -813,6 +813,7 @@ public class Chunk implements IChunkAccess {
while (iterator.hasNext()) {
Entity entity1 = (Entity) iterator.next();
@ -34,7 +34,7 @@ index 0afa8a7ebd8dbdfaac362d66b687e787bc040dee..8e9ddca049f837ed1c5fc4aa9fd6a685
if (entity1.getBoundingBox().c(axisalignedbb) && entity1 != entity) {
if (predicate == null || predicate.test(entity1)) {
@@ -847,6 +848,7 @@ public class Chunk implements IChunkAccess {
@@ -850,6 +851,7 @@ public class Chunk implements IChunkAccess {
while (iterator.hasNext()) {
T entity = (T) iterator.next(); // CraftBukkit - decompile error
@ -42,7 +42,7 @@ index 0afa8a7ebd8dbdfaac362d66b687e787bc040dee..8e9ddca049f837ed1c5fc4aa9fd6a685
if ((entitytypes == null || entity.getEntityType() == entitytypes) && entity.getBoundingBox().c(axisalignedbb) && predicate.test(entity)) {
list.add(entity);
@@ -868,6 +870,7 @@ public class Chunk implements IChunkAccess {
@@ -871,6 +873,7 @@ public class Chunk implements IChunkAccess {
while (iterator.hasNext()) {
T t0 = (T) iterator.next(); // CraftBukkit - decompile error

View file

@ -81,10 +81,10 @@ index 4ba72275b965693f3650f9b4fb138d3320d1b88b..572679e4d1ca0d84a08a5c48542fa40d
+ }
}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 8e9ddca049f837ed1c5fc4aa9fd6a6858dbc36be..165cb994e84bbcbdeb5ec14b561433257fd0df28 100644
index 5453eaae5b165a76b55a085d70081159b8e66770..4f05468590e30f4b11599d3841418c76519255e4 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -492,6 +492,7 @@ public class Chunk implements IChunkAccess {
@@ -495,6 +495,7 @@ public class Chunk implements IChunkAccess {
if (i != this.loc.x || j != this.loc.z) {
Chunk.LOGGER.warn("Wrong location! ({}, {}) should be ({}, {}), {}", i, j, this.loc.x, this.loc.z, entity);
entity.dead = true;
@ -197,7 +197,7 @@ index 4ee26ff08f7a058648ab54f0dcd81b466a9aced1..1d255ce3833a0ea735bedbb33ae82597
ChunkCoordIntPair chunkcoordintpair = playerchunk.i();
CompletableFuture<Either<List<IChunkAccess>, PlayerChunk.Failure>> completablefuture = this.a(chunkcoordintpair, 1, (i) -> {
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index b8b83554e2a7d7d0119ecf479d8e0bef556f775f..f10cb6378b1d9d2e7e28b5897a7098f9441b4f8a 100644
index a699c5e0b240fac3066e874e7d52f061d01e0c5a..55c0b5dc30cff8de5a83a97ae17fec7624cbe3d9 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -3,6 +3,8 @@ package net.minecraft.server;

View file

@ -1008,10 +1008,10 @@ index 0000000000000000000000000000000000000000..2eff19f6aaa31245f80910c6fbb541e3
+ }
+}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index af0d6aff4de78e81fd3feb16719efdccc05ccb90..2604fe9756e90cb70d3d527edddb917772e70973 100644
index 820033289cbeb782429b26b6bcabc3835b0101a3..b855589d978d06e9883daff97c9e702d5a9461cc 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -416,7 +416,7 @@ public class Chunk implements IChunkAccess {
@@ -419,7 +419,7 @@ public class Chunk implements IChunkAccess {
return null;
}

View file

@ -14,7 +14,7 @@ And since minecart hoppers are used _very_ rarely near we can avoid alot of sear
Combined, this adds up a lot.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 2604fe9756e90cb70d3d527edddb917772e70973..a2a0ca3394c3231aad9888fecebdaf82d4d9e9f7 100644
index b855589d978d06e9883daff97c9e702d5a9461cc..9f0758aff6588736d500b6e202fc1a5f6a577e7f 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -84,6 +84,10 @@ public class Chunk implements IChunkAccess {
@ -28,7 +28,7 @@ index 2604fe9756e90cb70d3d527edddb917772e70973..a2a0ca3394c3231aad9888fecebdaf82
// Paper end
public Chunk(World world, ChunkCoordIntPair chunkcoordintpair, BiomeStorage biomestorage, ChunkConverter chunkconverter, TickList<Block> ticklist, TickList<FluidType> ticklist1, long i, @Nullable ChunkSection[] achunksection, @Nullable Consumer<Chunk> consumer) {
@@ -532,6 +536,13 @@ public class Chunk implements IChunkAccess {
@@ -535,6 +539,13 @@ public class Chunk implements IChunkAccess {
entity.chunkZ = this.loc.z;
this.entities.add(entity); // Paper - per chunk entity list
this.entitySlices[k].add(entity);
@ -42,7 +42,7 @@ index 2604fe9756e90cb70d3d527edddb917772e70973..a2a0ca3394c3231aad9888fecebdaf82
entity.entitySlice = this.entitySlices[k]; // Paper
this.markDirty(); // Paper
}
@@ -564,6 +575,11 @@ public class Chunk implements IChunkAccess {
@@ -567,6 +578,11 @@ public class Chunk implements IChunkAccess {
if (!this.entitySlices[i].remove(entity)) {
return;
}
@ -54,7 +54,7 @@ index 2604fe9756e90cb70d3d527edddb917772e70973..a2a0ca3394c3231aad9888fecebdaf82
entityCounts.decrement(entity.getMinecraftKeyString());
this.markDirty(); // Paper
// Paper end
@@ -847,6 +863,14 @@ public class Chunk implements IChunkAccess {
@@ -850,6 +866,14 @@ public class Chunk implements IChunkAccess {
for (int k = i; k <= j; ++k) {
Iterator iterator = this.entitySlices[k].iterator(); // Spigot
@ -69,7 +69,7 @@ index 2604fe9756e90cb70d3d527edddb917772e70973..a2a0ca3394c3231aad9888fecebdaf82
while (iterator.hasNext()) {
T entity = (T) iterator.next(); // CraftBukkit - decompile error
if (entity.shouldBeRemoved) continue; // Paper
@@ -866,9 +890,29 @@ public class Chunk implements IChunkAccess {
@@ -869,9 +893,29 @@ public class Chunk implements IChunkAccess {
i = MathHelper.clamp(i, 0, this.entitySlices.length - 1);
j = MathHelper.clamp(j, 0, this.entitySlices.length - 1);

View file

@ -8,10 +8,10 @@ Sets tracking range of watermobs to animals instead of misc and simplifies code
Also ignores Enderdragon, defaulting it to Mojang's setting
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 692388821a795f60ffab8459475a764e1c409e2e..6eb055913177b0c01a027b2b356190dc561072c5 100644
index 7984dedfde6ba41db873f2de99ba01b6622ea6c7..b1f1372a76167a29f63917cedd1d6bfc99a97eba 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -1737,6 +1737,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1738,6 +1738,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
int j = entity.getEntityType().getChunkRange() * 16;

View file

@ -111,10 +111,10 @@ index a3a376e35eaf17b128048bd26a22eef713e7d535..3fcfe416d26808fa1c9bfdc5b413b149
return this.d(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index a2a0ca3394c3231aad9888fecebdaf82d4d9e9f7..bb95fe20e8aee58cf20fa764000b9f9123f367d3 100644
index 9f0758aff6588736d500b6e202fc1a5f6a577e7f..2cb0005909e9a77d2bd594cab0a75b259882cadb 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -586,8 +586,8 @@ public class Chunk implements IChunkAccess {
@@ -589,8 +589,8 @@ public class Chunk implements IChunkAccess {
this.entities.remove(entity); // Paper
}

View file

@ -8,10 +8,10 @@ faster on its own, however removing the try catch makes it
easier to inline due to code size
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index bb95fe20e8aee58cf20fa764000b9f9123f367d3..33456b0bb421d253aa8366210f41a9da7dcd1699 100644
index 2cb0005909e9a77d2bd594cab0a75b259882cadb..234770236fdc8d37996fb8b7e0b4ed2491e31633 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -379,17 +379,20 @@ public class Chunk implements IChunkAccess {
@@ -382,17 +382,20 @@ public class Chunk implements IChunkAccess {
}
public Fluid a(int i, int j, int k) {
@ -39,7 +39,7 @@ index bb95fe20e8aee58cf20fa764000b9f9123f367d3..33456b0bb421d253aa8366210f41a9da
CrashReport crashreport = CrashReport.a(throwable, "Getting fluid state");
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Block being got");
@@ -398,6 +401,7 @@ public class Chunk implements IChunkAccess {
@@ -401,6 +404,7 @@ public class Chunk implements IChunkAccess {
});
throw new ReportedException(crashreport);
}

View file

@ -7,10 +7,10 @@ Suspected case would be around the technique used in .stopRiding
Stack will identify any causer of this and warn instead of crashing.
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 6eb055913177b0c01a027b2b356190dc561072c5..4beae504c875767ff00e26461fe7240498750e27 100644
index b1f1372a76167a29f63917cedd1d6bfc99a97eba..c900bfb9edf957ebdbd83cc44280440648288250 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -1446,6 +1446,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1447,6 +1447,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
protected void addEntity(Entity entity) {
org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot

View file

@ -83,7 +83,7 @@ index 9f8c0e10e42d233a8b74ee5a71fb8fb6ea8e7480..0d1065688b19ceca9440bc8bf2bf6591
List<PlayerChunk> allChunks = new ArrayList<>(visibleChunks.values());
List<EntityPlayer> players = world.players;
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 4beae504c875767ff00e26461fe7240498750e27..75906f794205f5b7fe894163e1b13bfd85c2b419 100644
index c900bfb9edf957ebdbd83cc44280440648288250..8cd77117cdb81e3fbd196415f8ac82d3aeddcb12 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -55,8 +55,33 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -205,7 +205,7 @@ index 4beae504c875767ff00e26461fe7240498750e27..75906f794205f5b7fe894163e1b13bfd
IChunkAccess ichunkaccess = (IChunkAccess) playerchunk.getChunkSave().getNow(null); // CraftBukkit - decompile error
if (ichunkaccess instanceof ProtoChunkExtension || ichunkaccess instanceof Chunk) {
@@ -610,7 +679,20 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -611,7 +680,20 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
if (!this.updatingChunksModified) {
return false;
} else {
@ -227,7 +227,7 @@ index 4beae504c875767ff00e26461fe7240498750e27..75906f794205f5b7fe894163e1b13bfd
this.updatingChunksModified = false;
return true;
}
@@ -1076,12 +1158,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1077,12 +1159,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
protected Iterable<PlayerChunk> f() {
@ -243,7 +243,7 @@ index 4beae504c875767ff00e26461fe7240498750e27..75906f794205f5b7fe894163e1b13bfd
while (objectbidirectionaliterator.hasNext()) {
Entry<PlayerChunk> entry = (Entry) objectbidirectionaliterator.next();
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 5e84bbad1ba75cb2b541a29d38d3f96832cff853..2393c8715603478142a1980a9a769de58f8bb3c4 100644
index 5f51e8c05a822dfad35bcfa4c9a33f1f067e85a7..efa92c798010b4815b4aa63fe1e4832eeeccd9e9 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -74,6 +74,7 @@ import net.minecraft.server.GameRules;

View file

@ -11,7 +11,7 @@ Less crammed entities are likely to show significantly less benefit.
Effectively, this patch optimises crammed entity situations.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 33456b0bb421d253aa8366210f41a9da7dcd1699..750fb07756f7e40b21f8ab0925f2e842aae50f7b 100644
index 234770236fdc8d37996fb8b7e0b4ed2491e31633..d73987ffc416f47eb6231013a76420bc71c34f0e 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -90,6 +90,54 @@ public class Chunk implements IChunkAccess {
@ -69,7 +69,7 @@ index 33456b0bb421d253aa8366210f41a9da7dcd1699..750fb07756f7e40b21f8ab0925f2e842
public Chunk(World world, ChunkCoordIntPair chunkcoordintpair, BiomeStorage biomestorage, ChunkConverter chunkconverter, TickList<Block> ticklist, TickList<FluidType> ticklist1, long i, @Nullable ChunkSection[] achunksection, @Nullable Consumer<Chunk> consumer) {
this.sections = new ChunkSection[16];
this.e = Maps.newHashMap();
@@ -539,7 +587,7 @@ public class Chunk implements IChunkAccess {
@@ -542,7 +590,7 @@ public class Chunk implements IChunkAccess {
entity.chunkY = k;
entity.chunkZ = this.loc.z;
this.entities.add(entity); // Paper - per chunk entity list
@ -78,7 +78,7 @@ index 33456b0bb421d253aa8366210f41a9da7dcd1699..750fb07756f7e40b21f8ab0925f2e842
// Paper start
if (entity instanceof EntityItem) {
itemCounts[k]++;
@@ -576,7 +624,7 @@ public class Chunk implements IChunkAccess {
@@ -579,7 +627,7 @@ public class Chunk implements IChunkAccess {
entity.entitySlice = null;
entity.inChunk = false;
}

View file

@ -37,7 +37,7 @@ index 722db939971fe395d8250c388fbd7f3b5e87804d..ba99e9949c6fdfc4f49b6b6716100eb5
}
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 485e5d2778064c64c8dc8375b18c785649049184..a9f6c0835c3ae37b12d6b8b7ea59ccba7651a82a 100644
index 00ad80bb74bd581e3fa1bf82356ee5b7bc656bfe..9e2998f2214d6129e38acc0cbb59ce19f4c38759 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -131,6 +131,8 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -49,7 +49,7 @@ index 485e5d2778064c64c8dc8375b18c785649049184..a9f6c0835c3ae37b12d6b8b7ea59ccba
// Paper start - distance maps
private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<EntityPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
@@ -986,7 +988,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -987,7 +989,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
return Either.left(chunk);
});
}, (runnable) -> {

View file

@ -40,10 +40,10 @@ index 64e00275edf38739fe6e2d79dbcb93243e765678..a87aa07b17205b52e85f7d082fa4d516
// CraftBukkit end
public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index a9f6c0835c3ae37b12d6b8b7ea59ccba7651a82a..72d080fc3e5cec2310fd44ecf3acf11fb1d6d175 100644
index 9e2998f2214d6129e38acc0cbb59ce19f4c38759..50375629186e5cbe9fd6a36cae348f018cdac9d5 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -1538,6 +1538,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1539,6 +1539,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
.printStackTrace();
return;
}

View file

@ -44,7 +44,7 @@ index 3a88c9a67062eb73ad8257ea786efca7e7e99f65..6d3b34ead9cc95dcc1152dffa8c6c4a8
List<Entity> list = this.tracker.getPassengers();
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 1031f19b60fd3e2d4e567007f6989417248a1200..c6b1b5d83ee4d91ccf939b8ae3d188f6694e50cd 100644
index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac721a684ab5 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -143,21 +143,51 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -145,7 +145,7 @@ index 1031f19b60fd3e2d4e567007f6989417248a1200..c6b1b5d83ee4d91ccf939b8ae3d188f6
}
public void updatePlayerMobTypeMap(Entity entity) {
@@ -1435,17 +1503,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1436,17 +1504,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
public void movePlayer(EntityPlayer entityplayer) {
@ -164,7 +164,7 @@ index 1031f19b60fd3e2d4e567007f6989417248a1200..c6b1b5d83ee4d91ccf939b8ae3d188f6
int i = MathHelper.floor(entityplayer.locX()) >> 4;
int j = MathHelper.floor(entityplayer.locZ()) >> 4;
@@ -1562,7 +1620,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1563,7 +1621,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker);
@ -173,7 +173,7 @@ index 1031f19b60fd3e2d4e567007f6989417248a1200..c6b1b5d83ee4d91ccf939b8ae3d188f6
if (entity instanceof EntityPlayer) {
EntityPlayer entityplayer = (EntityPlayer) entity;
@@ -1606,7 +1664,37 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1607,7 +1665,37 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
entity.tracker = null; // Paper - We're no longer tracked
}
@ -211,7 +211,7 @@ index 1031f19b60fd3e2d4e567007f6989417248a1200..c6b1b5d83ee4d91ccf939b8ae3d188f6
List<EntityPlayer> list = Lists.newArrayList();
List<EntityPlayer> list1 = this.world.getPlayers();
@@ -1674,23 +1762,31 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1675,23 +1763,31 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
PacketDebug.a(this.world, chunk.getPos());
List<Entity> list = Lists.newArrayList();
List<Entity> list1 = Lists.newArrayList();
@ -255,7 +255,7 @@ index 1031f19b60fd3e2d4e567007f6989417248a1200..c6b1b5d83ee4d91ccf939b8ae3d188f6
Iterator iterator;
Entity entity1;
@@ -1728,7 +1824,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1729,7 +1825,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
public class EntityTracker {
@ -264,7 +264,7 @@ index 1031f19b60fd3e2d4e567007f6989417248a1200..c6b1b5d83ee4d91ccf939b8ae3d188f6
private final Entity tracker;
private final int trackingDistance;
private SectionPosition e;
@@ -1745,6 +1841,42 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1746,6 +1842,42 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.e = SectionPosition.a(entity);
}
@ -307,7 +307,7 @@ index 1031f19b60fd3e2d4e567007f6989417248a1200..c6b1b5d83ee4d91ccf939b8ae3d188f6
public boolean equals(Object object) {
return object instanceof PlayerChunkMap.EntityTracker ? ((PlayerChunkMap.EntityTracker) object).tracker.getId() == this.tracker.getId() : false;
}
@@ -1841,7 +1973,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1842,7 +1974,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
int j = entity.getEntityType().getChunkRange() * 16;
j = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, j); // Paper

View file

@ -192,7 +192,7 @@ index afc92dd031cdaf725b85c0b301d5a5a21da54720..6980d19f36c18cdbed6679dbdf04afd6
// Paper start
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index c6b1b5d83ee4d91ccf939b8ae3d188f6694e50cd..d5d74136b3add9fffa91762bd4100839377b5a27 100644
index 7e0e9b74327a76c79658e0bcc61fac721a684ab5..7380270ae89f3fe134ec76a265f8074b6406f558 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -153,6 +153,17 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -308,7 +308,7 @@ index c6b1b5d83ee4d91ccf939b8ae3d188f6694e50cd..d5d74136b3add9fffa91762bd4100839
}
if (playerchunk != null) {
@@ -1432,30 +1487,53 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1433,30 +1488,53 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
return isOutsideOfRange(chunkcoordintpair, false);
}

View file

@ -23,7 +23,7 @@ index 4612697569fd6e3683b0e58453b61a9a8d077229..5c8a946d5c895fc2622c7df656cc462c
+ }
}
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 750fb07756f7e40b21f8ab0925f2e842aae50f7b..8c1f3290d23795b58a30274c9437dc7dc43fa3a1 100644
index d73987ffc416f47eb6231013a76420bc71c34f0e..fc332dd824ecb4237edbf2974cfe036309d9765c 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -245,7 +245,51 @@ public class Chunk implements IChunkAccess {
@ -77,7 +77,7 @@ index 750fb07756f7e40b21f8ab0925f2e842aae50f7b..8c1f3290d23795b58a30274c9437dc7d
+ // Paper end - no-tick view distance
}
public final boolean areNeighboursLoaded(final int radius) {
public final boolean isAnyNeighborsLoaded() {
diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
index 353b186060b2c0417a49ab3865ea5972c859b016..586a20fe5c77c2ad5fa26f337a94a16e21d8b5e2 100644
--- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
@ -207,7 +207,7 @@ index 6980d19f36c18cdbed6679dbdf04afd694e078b6..03fb688fe4bdc19b4bc36b1f1d5b40c6
public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> a(ChunkStatus chunkstatus, PlayerChunkMap playerchunkmap) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index d5d74136b3add9fffa91762bd4100839377b5a27..3bac99d0a8453a2acc2a0fcc0c4501c12b251c29 100644
index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae414275164a 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -94,7 +94,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -340,7 +340,7 @@ index d5d74136b3add9fffa91762bd4100839377b5a27..3bac99d0a8453a2acc2a0fcc0c4501c1
}
public void updatePlayerMobTypeMap(Entity entity) {
@@ -1125,15 +1211,11 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1126,15 +1212,11 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
completablefuture1.thenAcceptAsync((either) -> {
either.mapLeft((chunk) -> {
this.u.getAndIncrement();
@ -358,7 +358,7 @@ index d5d74136b3add9fffa91762bd4100839377b5a27..3bac99d0a8453a2acc2a0fcc0c4501c1
});
return completablefuture1;
}
@@ -1233,32 +1315,38 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1234,32 +1316,38 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
} // Paper
}
@ -412,7 +412,7 @@ index d5d74136b3add9fffa91762bd4100839377b5a27..3bac99d0a8453a2acc2a0fcc0c4501c1
protected void sendChunk(EntityPlayer entityplayer, ChunkCoordIntPair chunkcoordintpair, Packet<?>[] apacket, boolean flag, boolean flag1) {
if (entityplayer.world == this.world) {
@@ -1266,7 +1354,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1267,7 +1355,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
PlayerChunk playerchunk = this.getVisibleChunk(chunkcoordintpair.pair());
if (playerchunk != null) {
@ -421,7 +421,7 @@ index d5d74136b3add9fffa91762bd4100839377b5a27..3bac99d0a8453a2acc2a0fcc0c4501c1
if (chunk != null) {
this.a(entityplayer, apacket, chunk);
@@ -1535,6 +1623,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1536,6 +1624,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
// Paper end - optimise isOutsideOfRange
@ -429,7 +429,7 @@ index d5d74136b3add9fffa91762bd4100839377b5a27..3bac99d0a8453a2acc2a0fcc0c4501c1
private boolean b(EntityPlayer entityplayer) {
return entityplayer.isSpectator() && !this.world.getGameRules().getBoolean(GameRules.SPECTATORS_GENERATE_CHUNKS);
}
@@ -1562,13 +1651,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1563,13 +1652,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.removePlayerFromDistanceMaps(entityplayer); // Paper - distance maps
}
@ -444,7 +444,7 @@ index d5d74136b3add9fffa91762bd4100839377b5a27..3bac99d0a8453a2acc2a0fcc0c4501c1
}
@@ -1576,7 +1659,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1577,7 +1660,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
SectionPosition sectionposition = SectionPosition.a((Entity) entityplayer);
entityplayer.a(sectionposition);
@ -453,7 +453,7 @@ index d5d74136b3add9fffa91762bd4100839377b5a27..3bac99d0a8453a2acc2a0fcc0c4501c1
return sectionposition;
}
@@ -1621,6 +1704,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1622,6 +1705,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
int k1;
int l1;
@ -461,7 +461,7 @@ index d5d74136b3add9fffa91762bd4100839377b5a27..3bac99d0a8453a2acc2a0fcc0c4501c1
if (Math.abs(i1 - i) <= this.viewDistance * 2 && Math.abs(j1 - j) <= this.viewDistance * 2) {
k1 = Math.min(i, i1) - this.viewDistance;
l1 = Math.min(j, j1) - this.viewDistance;
@@ -1658,7 +1742,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1659,7 +1743,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.sendChunk(entityplayer, chunkcoordintpair1, new Packet[2], false, true);
}
}
@ -470,7 +470,7 @@ index d5d74136b3add9fffa91762bd4100839377b5a27..3bac99d0a8453a2acc2a0fcc0c4501c1
this.updateMaps(entityplayer); // Paper - distance maps
@@ -1666,11 +1750,46 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1667,11 +1751,46 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@Override
public Stream<EntityPlayer> a(ChunkCoordIntPair chunkcoordintpair, boolean flag) {
@ -521,7 +521,7 @@ index d5d74136b3add9fffa91762bd4100839377b5a27..3bac99d0a8453a2acc2a0fcc0c4501c1
}
protected void addEntity(Entity entity) {
@@ -1830,6 +1949,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1831,6 +1950,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
@ -529,7 +529,7 @@ index d5d74136b3add9fffa91762bd4100839377b5a27..3bac99d0a8453a2acc2a0fcc0c4501c1
private void a(EntityPlayer entityplayer, Packet<?>[] apacket, Chunk chunk) {
if (apacket[0] == null) {
apacket[0] = new PacketPlayOutMapChunk(chunk, 65535);
@@ -2015,7 +2135,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -2016,7 +2136,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(this.tracker.chunkX, this.tracker.chunkZ);
PlayerChunk playerchunk = PlayerChunkMap.this.getVisibleChunk(chunkcoordintpair.pair());

View file

@ -39,10 +39,10 @@ index 6d3b34ead9cc95dcc1152dffa8c6c4a8c7f1d58b..5cc89c0cf9e9e632212a9653391437cb
if (!flag4 && this.o <= 400 && !this.q && this.r == this.tracker.onGround) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 3cd9e1238d944d77245404de0d926731d9ee4c1a..fa4e27011bde8838729c9f0a812bb68bd05a6169 100644
index 1c3526dda5c20264e21d079fd1aff1a735a9e496..2dd7999b6a540efd1e2e974f33ed87a6d0a8e8f1 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -2131,9 +2131,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -2132,9 +2132,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
public void updatePlayer(EntityPlayer entityplayer) {
org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
if (entityplayer != this.tracker) {

View file

@ -12,7 +12,7 @@ to the client, so that it doesn't attempt to calculate them.
This mitigates the frametime impact to a minimum (but it's still there).
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 8c1f3290d23795b58a30274c9437dc7dc43fa3a1..33cca62d90bf037df1b0b4e901baedb91400aee7 100644
index fc332dd824ecb4237edbf2974cfe036309d9765c..f22c37be6e779e569db6016b633872fefa20b1a2 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -277,7 +277,7 @@ public class Chunk implements IChunkAccess {
@ -37,7 +37,7 @@ index b7b06e082e59f8518be2036637385c7710d524ea..71da9f00b8a969e84414066fb1852cec
return chunksection == Chunk.a || chunksection.c();
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index fa4e27011bde8838729c9f0a812bb68bd05a6169..48a3cf7e4f82818964a33c46b63e1121c97dcc26 100644
index 2dd7999b6a540efd1e2e974f33ed87a6d0a8e8f1..4a9d6f0c193c6d8a65d548ac1dd1461e7056f0a4 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -402,7 +402,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -49,7 +49,7 @@ index fa4e27011bde8838729c9f0a812bb68bd05a6169..48a3cf7e4f82818964a33c46b63e1121
},
(EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> newState) -> {
@@ -1956,12 +1956,112 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1957,12 +1957,112 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}

View file

@ -602,7 +602,7 @@ index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..b8fe42e8123e972b1ec97b048c35d901
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 48a3cf7e4f82818964a33c46b63e1121c97dcc26..8b320d54132fdcc6606ea5f9eeec1602a9cd3bc5 100644
index 4a9d6f0c193c6d8a65d548ac1dd1461e7056f0a4..2b09437642ec846d025b226692f2290f9bb5b556 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -50,6 +50,7 @@ import org.apache.commons.lang3.mutable.MutableBoolean;
@ -756,7 +756,7 @@ index 48a3cf7e4f82818964a33c46b63e1121c97dcc26..8b320d54132fdcc6606ea5f9eeec1602
list.add(completablefuture);
}
@@ -1021,14 +1114,22 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1022,14 +1115,22 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
};
CompletableFuture<NBTTagCompound> chunkSaveFuture = this.world.asyncChunkTaskManager.getChunkSaveFuture(chunkcoordintpair.x, chunkcoordintpair.z);
@ -784,7 +784,7 @@ index 48a3cf7e4f82818964a33c46b63e1121c97dcc26..8b320d54132fdcc6606ea5f9eeec1602
return ret;
// Paper end
}
@@ -1157,7 +1258,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1158,7 +1259,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
long i = playerchunk.i().pair();
playerchunk.getClass();

View file

@ -0,0 +1,81 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 25 May 2020 11:02:42 -0400
Subject: [PATCH] Unload leaked Cached Chunks
Due to some complexity in mojangs complicated chain of juggling
whether or not a chunk should be unloaded when the last ticket is
removed, many chunks are remaining around in the cache.
These chunks are never being targetted for unload because they are
vastly out of view distance range and have no reason to be looked at.
This is a huge issue for performance because we have to iterate these
chunks EVERY TICK... This is what's been leading to high SELF time in
Ticking Chunks timings/profiler results.
We will now detect these chunks in that iteration, and automatically
add it to the unload queue when the chunk is found without any tickets.
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 54e89c9cc6c47ff2c4f4dd5d4c22a391f8a3d6e0..c9516d2d6724e84095e0e3c27c14870519fc05f9 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -898,6 +898,37 @@ public class ChunkProviderServer extends IChunkProvider {
if (chunksTicked[0]++ % 10 == 0) this.world.getMinecraftServer().midTickLoadChunks(); // Paper
}
}
+ // Paper start - remove inaccessible chunks leaked
+ else if (playerchunk.getTicketLevel() == playerchunk.oldTicketLevel &&
+ playerChunkMap.unloadQueue.size() < 100 &&
+ (playerchunk.lastStatusChange == 0 || world.getTime() - playerchunk.lastStatusChange > 20) &&
+ PlayerChunk.getChunkState(playerchunk.getTicketLevel()) == PlayerChunk.State.INACCESSIBLE
+ ) {
+ ChunkStatus chunkHolderStatus = playerchunk.getChunkHolderStatus();
+ ChunkStatus desiredStatus = PlayerChunk.getChunkStatus(playerchunk.getTicketLevel());
+ if (chunkHolderStatus != null && !chunkHolderStatus.isAtLeastStatus(desiredStatus)) {
+ return;
+ }
+
+ if (playerchunk.lastStatusChange == 0) {
+ playerchunk.lastStatusChange = world.getTime();
+ } else {
+ Chunk chunk = playerchunk.getChunk();
+ if (chunk != null && chunk.isAnyNeighborsLoaded()) {
+ playerchunk.lastStatusChange = world.getTime()+(20*5);
+ return;
+ }
+ long key = playerchunk.location.pair();
+ ArraySetSorted<Ticket<?>> tickets = playerChunkMap.chunkDistanceManager.tickets.get(key);
+ if (tickets == null || tickets.isEmpty()) {
+ playerchunk.lastStatusChange = world.getTime()+(20*30);
+ playerChunkMap.unloadQueue.add(key);
+ } else {
+ playerchunk.lastStatusChange = world.getTime()+(20*5);
+ }
+ }
+ // Paper end
+ }
});
this.world.getMethodProfiler().enter("customSpawners");
if (flag1) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
index b8fe42e8123e972b1ec97b048c35d90118076e66..7e4d37128738ad0ef44d14ef3b48d8c5aca0c2f5 100644
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
@@ -44,6 +44,7 @@ public class PlayerChunk {
long lastAutoSaveTime; // Paper - incremental autosave
long inactiveTimeStart; // Paper - incremental autosave
+ long lastStatusChange; // Paper - fix chunk leak
// Paper start - optimise isOutsideOfRange
// cached here to avoid a map lookup
@@ -562,6 +563,7 @@ public class PlayerChunk {
protected void a(PlayerChunkMap playerchunkmap) {
ChunkStatus chunkstatus = getChunkStatus(this.oldTicketLevel);
ChunkStatus chunkstatus1 = getChunkStatus(this.ticketLevel);
+ if (oldTicketLevel != ticketLevel) lastStatusChange = chunkMap.world.getTime(); // Paper - chunk leak
boolean flag = this.oldTicketLevel <= PlayerChunkMap.GOLDEN_TICKET;
boolean flag1 = this.ticketLevel <= PlayerChunkMap.GOLDEN_TICKET; // Paper - diff on change: (flag1 = new ticket level is in loadable range)
PlayerChunk.State playerchunk_state = getChunkState(this.oldTicketLevel);