PaperMC/Spigot-Server-Patches/0249-Avoid-Chunk-Lookups-for-Entity-TileEntity-Current-Ch.patch
Spottedleaf 994679a0c9 Fix patch "Faster redstone torch rapid clock removal" (#2014)
Tux pointed out the patch still has O(n^2) time complexity since
the sublist class in arraylist does not override clear() from
AbstractList, which uses a forward moving iterator to clear
the list.

Resolved by using a peek and poll from ArrayDeque.

This patch also removes the useless WeakHashMap which holds
the list (it mapped world->list) and replaces it with a
field on World.
2019-05-10 16:48:58 +01:00

77 lines
3.9 KiB
Diff

From 2b38cf192766111ee616781fcad9018b0ce05cbd Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 4 Jul 2018 03:39:51 -0400
Subject: [PATCH] Avoid Chunk Lookups for Entity/TileEntity Current Chunk
In many places where we simply want the current chunk the entity
is in, instead of doing a hashmap lookup for it, we now have access
to the object directly on the Entity/TileEntity object we can directly grab.
Use that local value instead to reduce lookups in many hot places.
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index c388a8261..463353bc7 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -762,7 +762,8 @@ public abstract class World implements IIBlockAccess, GeneratorAccess, AutoClose
if (!tileentity.isRemoved() && tileentity.hasWorld()) {
BlockPosition blockposition = tileentity.getPosition();
- if (this.isLoaded(blockposition) && this.getWorldBorder().a(blockposition)) {
+ Chunk currentChunk = tileentity.getCurrentChunk(); // Paper
+ if (currentChunk != null && this.getWorldBorder().a(blockposition)) { // Paper
try {
gameprofilerfiller.a(() -> {
return String.valueOf(TileEntityTypes.a(tileentity.q()));
@@ -796,7 +797,7 @@ public abstract class World implements IIBlockAccess, GeneratorAccess, AutoClose
this.tileEntityListTick.remove(tileTickPosition--);
// Spigot end
//this.tileEntityList.remove(tileentity); // Paper - remove unused list
- if (this.isLoaded(tileentity.getPosition())) {
+ if (tileentity.getCurrentChunk() != null ) { // Paper - avoid lookups
this.getChunkAtWorldCoords(tileentity.getPosition()).removeTileEntity(tileentity.getPosition());
}
}
@@ -817,8 +818,9 @@ public abstract class World implements IIBlockAccess, GeneratorAccess, AutoClose
}
// CraftBukkit end */
- if (this.isLoaded(tileentity1.getPosition())) {
- Chunk chunk = this.getChunkAtWorldCoords(tileentity1.getPosition());
+ Chunk chunk = tileentity1.getCurrentChunk(); // Paper
+ if (chunk != null) { // Paper
+ //Chunk chunk = this.getChunkAtWorldCoords(tileentity1.getPosition()); // Paper
IBlockData iblockdata = chunk.getType(tileentity1.getPosition());
chunk.setTileEntity(tileentity1.getPosition(), tileentity1);
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 0e559133f..1c92cf58a 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -1068,7 +1068,7 @@ public class WorldServer extends World {
}
this.entitiesByUUID.remove(entity.getUniqueID());
- this.getChunkProvider().removeEntity(entity);
+ this.getChunkProvider().removeEntity(entity); // Paper
if (entity instanceof EntityPlayer) {
EntityPlayer entityplayer = (EntityPlayer) entity;
@@ -1128,9 +1128,12 @@ public class WorldServer extends World {
}
private void removeEntityFromChunk(Entity entity) {
- IChunkAccess ichunkaccess = this.getChunkAt(entity.chunkX, entity.chunkZ, ChunkStatus.FULL, false);
+ // Paper start
+ if (!entity.inChunk) return;
+ IChunkAccess ichunkaccess = this.getChunkIfLoaded(entity.chunkX, entity.chunkZ);
+ // Paper start
- if (ichunkaccess instanceof Chunk) {
+ if (ichunkaccess != null) {
((Chunk) ichunkaccess).b(entity);
}
--
2.21.0