From a12c0881a098b6e671211ece2fde3955e8284c7d Mon Sep 17 00:00:00 2001 From: Colin Godsey Date: Wed, 8 Aug 2018 15:22:58 -0600 Subject: [PATCH] add entity count cache #1207 --- .../0333-Add-entity-count-cache.patch | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 Spigot-Server-Patches/0333-Add-entity-count-cache.patch diff --git a/Spigot-Server-Patches/0333-Add-entity-count-cache.patch b/Spigot-Server-Patches/0333-Add-entity-count-cache.patch new file mode 100644 index 000000000..98234e4eb --- /dev/null +++ b/Spigot-Server-Patches/0333-Add-entity-count-cache.patch @@ -0,0 +1,148 @@ +From 81259e2cb7b30df39c3d1b23d66ec2c1bdde2a5d Mon Sep 17 00:00:00 2001 +From: Colin Godsey +Date: Wed, 8 Aug 2018 16:10:06 -0600 +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 +index 004c3ec4..09c2bc32 100644 +--- 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 entityList = new java.util.ArrayList() + { ++ // Paper start - entity count cache ++ @Override ++ public boolean addAll(Collection c) { ++ for(Entity e : c) { ++ updateEntityCount(e, true); ++ } ++ ++ return super.addAll(c); ++ } ++ ++ @Override ++ public boolean removeAll(Collection c) { ++ for(Object e : c) { ++ if(e instanceof Entity) { ++ 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(); ++ if(o instanceof Entity) updateEntityCount((Entity)o, false); // Paper + return super.remove( o ); + } + +@@ -82,6 +114,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose + public final Map playersByName = Maps.newHashMap(); // Paper - World EntityHuman Lookup Optimizations + public final List k = Lists.newArrayList(); + protected final IntHashMap entitiesById = new IntHashMap(); ++ private Map, 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(); +@@ -2439,19 +2472,16 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose + + } + +- public int a(Class oclass) { ++ // Paper start - entity count cache ++ private int countEntityType(Class oclass) { + int i = 0; + Iterator iterator = this.entityList.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); +- if (entity.shouldBeRemoved) continue; // Paper + // CraftBukkit start - Split out persistent check, don't apply it to special persistent mobs +- if (entity instanceof EntityInsentient) { +- EntityInsentient entityinsentient = (EntityInsentient) entity; +- if (entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) { +- continue; +- } ++ if (shouldIgnoreForCount(entity)) { ++ continue; + } + + if (oclass.isAssignableFrom(entity.getClass())) { +@@ -2464,6 +2494,52 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose + return i; + } + ++ public int getEntityCount(Class oclass) { return a(oclass); } // Paper - OBFHELPER ++ public int a(Class oclass) { ++ if(countCache.containsKey(oclass)) { ++ return countCache.get(oclass); ++ } else { ++ int count = countEntityType(oclass); ++ ++ countCache.put(oclass, count); ++ ++ return count; ++ } ++ } ++ ++ public boolean shouldIgnoreForCount(Entity entity) { ++ if (entity instanceof EntityInsentient) { ++ EntityInsentient entityinsentient = (EntityInsentient) entity; ++ return entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent(); ++ } ++ ++ return false; ++ } ++ ++ protected void updateEntityCount(Entity entity, boolean incr) { ++ if(entity == null) return; ++ if(shouldIgnoreForCount(entity)) return; ++ ++ countCache.replaceAll((clazz, count) -> { ++ if(clazz.isAssignableFrom(entity.getClass())) { ++ int newCount = count; ++ ++ if(incr) newCount++; ++ else newCount--; ++ ++ if(newCount < 0) { ++ e.warn("Entity count cache has gone negative"); ++ newCount = 0; ++ } ++ ++ return newCount; ++ } else { ++ return count; ++ } ++ }); ++ } ++ // Paper end ++ + public void addChunkEntities(Collection collection) { a(collection); } // Paper - OBFHELPER + public void a(Collection collection) { + org.spigotmc.AsyncCatcher.catchOp( "entity world add"); // Spigot +-- +2.15.2 (Apple Git-101.1) +