Update TileEntity optimizations (again again) ...

hopefully less often now
This commit is contained in:
Zach Brown 2014-08-11 23:07:39 -05:00
parent 169c67aaa0
commit 31d35e76ac
2 changed files with 127 additions and 83 deletions

View File

@ -1,6 +1,6 @@
From fa5a4c6926b45e62616bef1069f593d5b88d2166 Mon Sep 17 00:00:00 2001 From 85f6cf24d2cc67420285c6d695ddd33e5ff80f92 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co> From: Aikar <aikar@aikar.co>
Date: Mon, 11 Aug 2014 21:46:33 -0500 Date: Mon, 11 Aug 2014 23:00:13 -0500
Subject: [PATCH] Optimize TileEntity ticking Subject: [PATCH] Optimize TileEntity ticking
Re-organizes the servers TileEntity Tick List to be bucketed by type. Re-organizes the servers TileEntity Tick List to be bucketed by type.
@ -15,7 +15,7 @@ the server owner control on how fast a TileEntity ticks, slowing it down if they
(Such as chest), to improve performance. (Such as chest), to improve performance.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 0423ee9..09aa073 100644 index 0423ee9..e0d34d9 100644
--- a/src/main/java/net/minecraft/server/Chunk.java --- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -28,6 +28,7 @@ public class Chunk { @@ -28,6 +28,7 @@ public class Chunk {
@ -39,22 +39,27 @@ index 0423ee9..09aa073 100644
// Spigot End // Spigot End
- this.world.a(tileentity); - this.world.a(tileentity);
+ // this.world.a(tileentity); // Handled by Improved Tick List (Only loaded chunks iterate) + // this.world.a(tileentity); // PaperSpigot - Handled by Improved Tick List (Only loaded chunks iterate)
} }
for (int i = 0; i < this.entitySlices.length; ++i) { for (int i = 0; i < this.entitySlices.length; ++i) {
diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
index 3c5ec6f..50130ca 100644 index 3c5ec6f..009a7fb 100644
--- a/src/main/java/net/minecraft/server/TileEntity.java --- a/src/main/java/net/minecraft/server/TileEntity.java
+++ b/src/main/java/net/minecraft/server/TileEntity.java +++ b/src/main/java/net/minecraft/server/TileEntity.java
@@ -14,6 +14,7 @@ public class TileEntity { @@ -58,6 +58,12 @@ public class TileEntity {
}
// Spigot end
public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getTileEntityTimings(this); // Spigot + // PaperSpigot start - Optimized TileEntity Tick changes
private static final Logger a = LogManager.getLogger(); + private static int tileEntityCounter = 0;
+ public boolean isAdded = false; // PaperSpigot - optimize contains checks + public boolean isAdded = false;
private static Map i = new HashMap(); + public int tileId = tileEntityCounter++;
private static Map j = new HashMap(); + //PaperSpigot end
protected World world; +
public TileEntity() {}
private static void a(Class oclass, String s) {
diff --git a/src/main/java/net/minecraft/server/TileEntityBeacon.java b/src/main/java/net/minecraft/server/TileEntityBeacon.java diff --git a/src/main/java/net/minecraft/server/TileEntityBeacon.java b/src/main/java/net/minecraft/server/TileEntityBeacon.java
index 09313ea..86142f9 100644 index 09313ea..86142f9 100644
--- a/src/main/java/net/minecraft/server/TileEntityBeacon.java --- a/src/main/java/net/minecraft/server/TileEntityBeacon.java
@ -86,7 +91,7 @@ index c900caf..e27716b 100644
f = 5.0F; f = 5.0F;
List list = this.world.a(EntityHuman.class, AxisAlignedBB.a((double) ((float) this.x - f), (double) ((float) this.y - f), (double) ((float) this.z - f), (double) ((float) (this.x + 1) + f), (double) ((float) (this.y + 1) + f), (double) ((float) (this.z + 1) + f))); List list = this.world.a(EntityHuman.class, AxisAlignedBB.a((double) ((float) this.x - f), (double) ((float) this.y - f), (double) ((float) this.z - f), (double) ((float) (this.x + 1) + f), (double) ((float) (this.y + 1) + f), (double) ((float) (this.z + 1) + f)));
diff --git a/src/main/java/net/minecraft/server/TileEntityEnderChest.java b/src/main/java/net/minecraft/server/TileEntityEnderChest.java diff --git a/src/main/java/net/minecraft/server/TileEntityEnderChest.java b/src/main/java/net/minecraft/server/TileEntityEnderChest.java
index b205ab7..d76a2b2 100644 index b205ab7..c2b9e04 100644
--- a/src/main/java/net/minecraft/server/TileEntityEnderChest.java --- a/src/main/java/net/minecraft/server/TileEntityEnderChest.java
+++ b/src/main/java/net/minecraft/server/TileEntityEnderChest.java +++ b/src/main/java/net/minecraft/server/TileEntityEnderChest.java
@@ -11,7 +11,7 @@ public class TileEntityEnderChest extends TileEntity { @@ -11,7 +11,7 @@ public class TileEntityEnderChest extends TileEntity {
@ -112,7 +117,7 @@ index 143cffb..de33df0 100644
if (this.h instanceof BlockDaylightDetector) { if (this.h instanceof BlockDaylightDetector) {
((BlockDaylightDetector) this.h).e(this.world, this.x, this.y, this.z); ((BlockDaylightDetector) this.h).e(this.world, this.x, this.y, this.z);
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 33c228b..940e1c8 100644 index 33c228b..fb0a6a8 100644
--- a/src/main/java/net/minecraft/server/World.java --- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java
@@ -58,7 +58,7 @@ public abstract class World implements IBlockAccess { @@ -58,7 +58,7 @@ public abstract class World implements IBlockAccess {
@ -120,10 +125,19 @@ index 33c228b..940e1c8 100644
// Spigot end // Spigot end
protected List f = new ArrayList(); protected List f = new ArrayList();
- public Set tileEntityList = new HashSet(); // CraftBukkit - ArrayList -> HashSet - public Set tileEntityList = new HashSet(); // CraftBukkit - ArrayList -> HashSet
+ public Set tileEntityList = new org.github.paperspigot.WorldTileEntityList(this); // CraftBukkit - ArrayList -> HashSet // PaperSpigot + public Set tileEntityList = new org.github.paperspigot.WorldTileEntityList(this); // PaperSpigot // CraftBukkit - ArrayList -> HashSet
private List a = new ArrayList(); private List a = new ArrayList();
private List b = new ArrayList(); private List b = new ArrayList();
public List players = new ArrayList(); public List players = new ArrayList();
@@ -1513,7 +1513,7 @@ public abstract class World implements IBlockAccess {
}
// Spigot end
- if (!tileentity.r() && tileentity.o() && this.isLoaded(tileentity.x, tileentity.y, tileentity.z)) {
+ if (!tileentity.r() && tileentity.o() /*&& this.isLoaded(tileentity.x, tileentity.y, tileentity.z)*/) { // PaperSpigot - remove isLoaded check - done by the iterator per chunk
try {
tileentity.tickTimer.startTiming(); // Spigot
tileentity.h();
@@ -1529,13 +1529,13 @@ public abstract class World implements IBlockAccess { @@ -1529,13 +1529,13 @@ public abstract class World implements IBlockAccess {
if (tileentity.r()) { if (tileentity.r()) {
@ -142,25 +156,27 @@ index 33c228b..940e1c8 100644
diff --git a/src/main/java/org/github/paperspigot/ChunkTileEntityList.java b/src/main/java/org/github/paperspigot/ChunkTileEntityList.java diff --git a/src/main/java/org/github/paperspigot/ChunkTileEntityList.java b/src/main/java/org/github/paperspigot/ChunkTileEntityList.java
new file mode 100644 new file mode 100644
index 0000000..e673ba9 index 0000000..cb4a34e
--- /dev/null --- /dev/null
+++ b/src/main/java/org/github/paperspigot/ChunkTileEntityList.java +++ b/src/main/java/org/github/paperspigot/ChunkTileEntityList.java
@@ -0,0 +1,121 @@ @@ -0,0 +1,153 @@
+package org.github.paperspigot; +package org.github.paperspigot;
+ +
+import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ListMultimap; +import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Maps;
+import net.minecraft.server.*; +import net.minecraft.server.*;
+import net.minecraft.util.gnu.trove.map.hash.TObjectIntHashMap; +import net.minecraft.util.gnu.trove.map.hash.TObjectIntHashMap;
+ +
+import java.util.Collection;
+import java.util.Iterator; +import java.util.Iterator;
+import java.util.List;
+import java.util.Map; +import java.util.Map;
+ +
+public class ChunkTileEntityList { +public class ChunkTileEntityList {
+ final ListMultimap<Class, TileEntity> tickList = ArrayListMultimap.create(); + final Map<Class<? extends TileEntity>, ListMultimap<Integer, TileEntity>> tickList = Maps.newHashMap();
+ +
+ private static final TObjectIntHashMap<Class> tileEntityTickIntervals = new TObjectIntHashMap<Class>() {{ + private static final TObjectIntHashMap<Class<? extends TileEntity>> tileEntityTickIntervals =
+ new TObjectIntHashMap<Class<? extends TileEntity>>() {{
+ // Use 0 for no ticking + // Use 0 for no ticking
+ // These TE's have empty tick methods, doing nothing. Never bother ticking them. + // These TE's have empty tick methods, doing nothing. Never bother ticking them.
+ for (Class<? extends TileEntity> ignored : new Class[]{ + for (Class<? extends TileEntity> ignored : new Class[]{
@ -193,7 +209,7 @@ index 0000000..e673ba9
+ put(TileEntityLightDetector.class, 20); + put(TileEntityLightDetector.class, 20);
+ }}; + }};
+ +
+ public static Integer getInterval(Class cls) { + public static Integer getInterval(Class<? extends TileEntity> cls) {
+ Integer tickInterval = tileEntityTickIntervals.get(cls); + Integer tickInterval = tileEntityTickIntervals.get(cls);
+ return tickInterval != null ? tickInterval : 1; + return tickInterval != null ? tickInterval : 1;
+ } + }
@ -208,33 +224,63 @@ index 0000000..e673ba9
+ return new ChunkTileEntityIterator(); + return new ChunkTileEntityIterator();
+ } + }
+ +
+
+ public boolean add(TileEntity entity) { + public boolean add(TileEntity entity) {
+ entity.isAdded = true; + entity.isAdded = true;
+ return tickList.put(entity.getClass(), entity); + int bucket = getBucketId(entity);
+ ListMultimap<Integer, TileEntity> typeBucket = getBucket(entity);
+ return typeBucket.put(bucket, entity);
+ } + }
+ +
+ public boolean remove(TileEntity entity) { + public boolean remove(TileEntity entity) {
+ if (!entity.isAdded) {
+ return false;
+ }
+ entity.isAdded = false; + entity.isAdded = false;
+ return tickList.remove(entity.getClass(), entity); + int bucket = getBucketId(entity);
+ ListMultimap<Integer, TileEntity> typeBucket = getBucket(entity);
+ return typeBucket.remove(bucket, entity);
+ }
+
+ private ListMultimap<Integer, TileEntity> getBucket(TileEntity entity) {
+ final Class<? extends TileEntity> cls = entity.getClass();
+
+ ListMultimap<Integer, TileEntity> typeBucket = tickList.get(cls);
+ if (typeBucket == null) {
+ typeBucket = ArrayListMultimap.create();
+ tickList.put(cls, typeBucket);
+ }
+ return typeBucket;
+ }
+
+ private static int getBucketId(TileEntity entity) {
+ Integer interval = getInterval(entity.getClass());
+ if (interval < 1) {
+ interval = 1; // Prevent divide by zero errors.
+ }
+ return entity.tileId % interval;
+ } + }
+ +
+ private class ChunkTileEntityIterator implements Iterator { + private class ChunkTileEntityIterator implements Iterator {
+ Iterator<Map.Entry<Class, Collection<TileEntity>>> typeIterator; + Iterator<Map.Entry<Class<? extends TileEntity>, ListMultimap<Integer, TileEntity>>> typeIterator;
+ Map.Entry<Class, Collection<TileEntity>> curType = null; + Map.Entry<Class <? extends TileEntity>, ListMultimap<Integer, TileEntity>> curType = null;
+ Iterator<TileEntity> listIterator = null; + Iterator<TileEntity> listIterator = null;
+ +
+ { + {
+ typeIterator = tickList.asMap().entrySet().iterator(); + typeIterator = tickList.entrySet().iterator();
+ nextType(); + nextType();
+ } + }
+ +
+ private boolean nextType() { + private boolean nextType() {
+ if (typeIterator.hasNext()) { + if (typeIterator.hasNext()) {
+ curType = typeIterator.next(); + curType = typeIterator.next();
+ final Integer interval = ChunkTileEntityList.getInterval(curType.getKey()); +
+ if (world.getTime() % interval != 0) { + final ListMultimap<Integer, TileEntity> buckets = curType.getValue();
+ listIterator = curType.getValue().iterator(); +
+ final Integer interval = getInterval(curType.getKey());
+ int bucket = (int) (world.getTime() % interval);
+ final List<TileEntity> tileList = buckets.get(bucket);
+ if (tileList != null && !tileList.isEmpty()) {
+ listIterator = tileList.iterator();
+ } else { + } else {
+ listIterator = null; + listIterator = null;
+ } + }
@ -267,10 +313,9 @@ index 0000000..e673ba9
+ } + }
+ } + }
+} +}
\ No newline at end of file
diff --git a/src/main/java/org/github/paperspigot/WorldTileEntityList.java b/src/main/java/org/github/paperspigot/WorldTileEntityList.java diff --git a/src/main/java/org/github/paperspigot/WorldTileEntityList.java b/src/main/java/org/github/paperspigot/WorldTileEntityList.java
new file mode 100644 new file mode 100644
index 0000000..d783741 index 0000000..5f57c6d
--- /dev/null --- /dev/null
+++ b/src/main/java/org/github/paperspigot/WorldTileEntityList.java +++ b/src/main/java/org/github/paperspigot/WorldTileEntityList.java
@@ -0,0 +1,106 @@ @@ -0,0 +1,106 @@
@ -299,7 +344,7 @@ index 0000000..d783741
+ */ + */
+ @Override + @Override
+ public boolean add(Object o) { + public boolean add(Object o) {
+ return o instanceof TileEntity && ChunkTileEntityList.getInterval(o.getClass()) > 0 && add((TileEntity) o); + return o instanceof TileEntity && ChunkTileEntityList.getInterval(((TileEntity)o).getClass()) > 0 && add((TileEntity) o);
+ } + }
+ +
+ private boolean add(TileEntity entity) { + private boolean add(TileEntity entity) {
@ -380,7 +425,6 @@ index 0000000..d783741
+ } + }
+ } + }
+} +}
\ No newline at end of file
-- --
1.9.1 1.9.1

View File

@ -1,6 +1,6 @@
From 280e4f94a1b0fc4a599baaeaa854ee2321990e9f Mon Sep 17 00:00:00 2001 From 8f5ed31e134327d8d6fffceacc0f873df8ea981a Mon Sep 17 00:00:00 2001
From: Zach Brown <Zbob750@live.com> From: Zach Brown <Zbob750@live.com>
Date: Mon, 11 Aug 2014 19:30:19 -0500 Date: Mon, 11 Aug 2014 23:03:47 -0500
Subject: [PATCH] Move sound handling out of the chest tick loop Subject: [PATCH] Move sound handling out of the chest tick loop
This allows us to disable ticking chests and enderchests without any This allows us to disable ticking chests and enderchests without any
@ -84,7 +84,7 @@ index e27716b..69ffd30 100644
if (this.q() == Blocks.TRAPPED_CHEST) { if (this.q() == Blocks.TRAPPED_CHEST) {
int newPower = Math.max(0, Math.min(15, this.o)); int newPower = Math.max(0, Math.min(15, this.o));
diff --git a/src/main/java/net/minecraft/server/TileEntityEnderChest.java b/src/main/java/net/minecraft/server/TileEntityEnderChest.java diff --git a/src/main/java/net/minecraft/server/TileEntityEnderChest.java b/src/main/java/net/minecraft/server/TileEntityEnderChest.java
index d76a2b2..339e133 100644 index c2b9e04..7298c4f 100644
--- a/src/main/java/net/minecraft/server/TileEntityEnderChest.java --- a/src/main/java/net/minecraft/server/TileEntityEnderChest.java
+++ b/src/main/java/net/minecraft/server/TileEntityEnderChest.java +++ b/src/main/java/net/minecraft/server/TileEntityEnderChest.java
@@ -16,6 +16,9 @@ public class TileEntityEnderChest extends TileEntity { @@ -16,6 +16,9 @@ public class TileEntityEnderChest extends TileEntity {
@ -147,10 +147,10 @@ index d76a2b2..339e133 100644
public boolean a(EntityHuman entityhuman) { public boolean a(EntityHuman entityhuman) {
diff --git a/src/main/java/org/github/paperspigot/ChunkTileEntityList.java b/src/main/java/org/github/paperspigot/ChunkTileEntityList.java diff --git a/src/main/java/org/github/paperspigot/ChunkTileEntityList.java b/src/main/java/org/github/paperspigot/ChunkTileEntityList.java
index e673ba9..dac6463 100644 index cb4a34e..128f5b2 100644
--- a/src/main/java/org/github/paperspigot/ChunkTileEntityList.java --- a/src/main/java/org/github/paperspigot/ChunkTileEntityList.java
+++ b/src/main/java/org/github/paperspigot/ChunkTileEntityList.java +++ b/src/main/java/org/github/paperspigot/ChunkTileEntityList.java
@@ -25,14 +25,14 @@ public class ChunkTileEntityList { @@ -27,14 +27,14 @@ public class ChunkTileEntityList {
TileEntityCommand.class, TileEntityCommand.class,
TileEntitySkull.class, TileEntitySkull.class,
TileEntityComparator.class, TileEntityComparator.class,