Paper/Spigot-Server-Patches/0333-Add-entity-count-cache.patch

153 lines
5.0 KiB
Diff
Raw Normal View History

2018-08-09 02:07:03 +02:00
From 3ac10ee43109b578232e3d127511e761ddc87a1a Mon Sep 17 00:00:00 2001
2018-08-08 23:22:58 +02:00
From: Colin Godsey <crgodsey@gmail.com>
2018-08-09 02:07:03 +02:00
Date: Wed, 8 Aug 2018 10:10:06 -0600
2018-08-08 23:22:58 +02:00
Subject: [PATCH] Add entity count cache
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
2018-08-09 02:07:03 +02:00
index 004c3ec47..c392595c0 100644
2018-08-08 23:22:58 +02:00
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -50,10 +50,41 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
// Spigot start - guard entity list from removals
public final List<Entity> entityList = new java.util.ArrayList<Entity>()
{
+ // Paper start - entity count cache
+ @Override
+ public boolean addAll(Collection<? extends Entity> c) {
2018-08-09 02:07:03 +02:00
+ for (Entity e : c) {
2018-08-08 23:22:58 +02:00
+ updateEntityCount(e, true);
+ }
+
+ return super.addAll(c);
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> c) {
2018-08-09 02:07:03 +02:00
+ for (Object e : c) {
+ if (e instanceof Entity) {
2018-08-08 23:22:58 +02:00
+ updateEntityCount((Entity)e, false);
+ }
+ }
+
+ return super.removeAll(c);
+ }
+
+ @Override
+ public boolean add(Entity e) {
+ updateEntityCount(e, true);
+
+ return super.add(e);
+ }
+
+ // Paper end
+
@Override
public Entity remove(int index)
{
guard();
+ updateEntityCount(get(index), false); // Paper
return super.remove( index );
}
@@ -61,6 +92,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
public boolean remove(Object o)
{
guard();
2018-08-09 02:07:03 +02:00
+ if (o instanceof Entity) updateEntityCount((Entity)o, false); // Paper
2018-08-08 23:22:58 +02:00
return super.remove( o );
}
@@ -82,6 +114,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
public final Map<String, EntityHuman> playersByName = Maps.newHashMap(); // Paper - World EntityHuman Lookup Optimizations
public final List<Entity> k = Lists.newArrayList();
protected final IntHashMap<Entity> entitiesById = new IntHashMap();
+ private Map<Class<?>, Integer> countCache = new HashMap(); // Paper
private final long G = 16777215L;
private int H; public int getSkylightSubtracted() { return this.H; } public void setSkylightSubtracted(int value) { this.H = value;} // Paper - OBFHELPER
protected int m = (new Random()).nextInt();
2018-08-09 02:07:03 +02:00
@@ -2440,6 +2473,8 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
2018-08-08 23:22:58 +02:00
}
2018-08-09 02:07:03 +02:00
public int a(Class<?> oclass) {
+ if (true) return getEntityCount(oclass); //Paper - short circuit to cached method
+
2018-08-08 23:22:58 +02:00
int i = 0;
Iterator iterator = this.entityList.iterator();
2018-08-09 02:07:03 +02:00
@@ -2464,6 +2499,71 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
2018-08-08 23:22:58 +02:00
return i;
}
2018-08-09 02:07:03 +02:00
+ // Paper start - entity count cache
+ private int countEntityType(Class<?> oclass) {
+ int i = 0;
+ Iterator iterator = this.entityList.iterator();
2018-08-08 23:22:58 +02:00
+
2018-08-09 02:07:03 +02:00
+ while (iterator.hasNext()) {
+ Entity entity = (Entity) iterator.next();
2018-08-08 23:22:58 +02:00
+
2018-08-09 02:07:03 +02:00
+ if (shouldIgnoreForCount(entity)) continue;
+ if (oclass.isAssignableFrom(entity.getClass())) i++;
2018-08-08 23:22:58 +02:00
+ }
2018-08-09 02:07:03 +02:00
+
+ return i;
+ }
+
+ public int getEntityCount(Class<?> oclass) {
+ Integer count = countCache.get(oclass);
+
+ if (count != null) return count;
+
+ count = countEntityType(oclass);
+
+ countCache.put(oclass, count);
+
+ return count;
2018-08-08 23:22:58 +02:00
+ }
+
+ public boolean shouldIgnoreForCount(Entity entity) {
2018-08-09 02:07:03 +02:00
+ if (entity == null) return true;
+
2018-08-08 23:22:58 +02:00
+ if (entity instanceof EntityInsentient) {
+ EntityInsentient entityinsentient = (EntityInsentient) entity;
+ return entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent();
+ }
+
+ return false;
+ }
+
2018-08-09 02:07:03 +02:00
+ protected void updateEntityCount(Class<?> clazz, boolean incr) {
+ Integer countObject = countCache.get(clazz);
2018-08-08 23:22:58 +02:00
+
2018-08-09 02:07:03 +02:00
+ if (countObject == null) return;
2018-08-08 23:22:58 +02:00
+
2018-08-09 02:07:03 +02:00
+ int count = countObject;
2018-08-08 23:22:58 +02:00
+
2018-08-09 02:07:03 +02:00
+ if (incr) count++;
+ else count--;
2018-08-08 23:22:58 +02:00
+
2018-08-09 02:07:03 +02:00
+ if(count < 0) {
+ e.warn("Entity count cache has gone negative");
+ count = 0;
+ }
+
+ countCache.put(clazz, count);
+ }
+
+ protected void updateEntityCount(Entity entity, boolean incr) {
+ if (shouldIgnoreForCount(entity)) return;
+
+ for (Class<?> clazz = entity.getClass() ; !clazz.equals(Object.class) ; clazz = clazz.getSuperclass()) {
+ updateEntityCount(clazz, incr);
+ }
2018-08-08 23:22:58 +02:00
+ }
+ // Paper end
+
public void addChunkEntities(Collection<Entity> collection) { a(collection); } // Paper - OBFHELPER
public void a(Collection<Entity> collection) {
org.spigotmc.AsyncCatcher.catchOp( "entity world add"); // Spigot
--
2.15.2 (Apple Git-101.1)