From 0436193bc840c9a1fd1d2c7c969687402852e0f0 Mon Sep 17 00:00:00 2001 From: Ammar Askar Date: Sun, 21 Apr 2013 00:25:59 +0500 Subject: [PATCH] Take the count mapping one step further by removing chunk traversal for count seeking altogether --- ...ies-in-chunks-being-processed-for-th.patch | 41 ++-------- ...ts-for-randomly-spawned-creatures-to.patch | 82 ++++++++----------- 2 files changed, 43 insertions(+), 80 deletions(-) diff --git a/CraftBukkit-Patches/0016-Only-count-entities-in-chunks-being-processed-for-th.patch b/CraftBukkit-Patches/0016-Only-count-entities-in-chunks-being-processed-for-th.patch index d89c892d20..0945ee1531 100644 --- a/CraftBukkit-Patches/0016-Only-count-entities-in-chunks-being-processed-for-th.patch +++ b/CraftBukkit-Patches/0016-Only-count-entities-in-chunks-being-processed-for-th.patch @@ -1,4 +1,4 @@ -From 9b80ec89a6c650410da797ad30fd6f6343d465a2 Mon Sep 17 00:00:00 2001 +From a6f63db4333363a12ea2905bc4a2093abde6839d Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 29 Jan 2013 13:25:53 -0500 Subject: [PATCH] Only count entities in chunks being processed for the spawn @@ -6,7 +6,7 @@ Subject: [PATCH] Only count entities in chunks being processed for the spawn diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java -index b3e2818..6362a37 100644 +index b3e2818..21fbf7d 100644 --- a/src/main/java/net/minecraft/server/SpawnerCreature.java +++ b/src/main/java/net/minecraft/server/SpawnerCreature.java @@ -16,6 +16,7 @@ public final class SpawnerCreature { @@ -17,34 +17,7 @@ index b3e2818..6362a37 100644 protected static ChunkPosition getRandomPosition(World world, int i, int j) { Chunk chunk = world.getChunkAt(i, j); -@@ -26,6 +27,26 @@ public final class SpawnerCreature { - return new ChunkPosition(k, i1, l); - } - -+ // Spigot start - get entity count only from chunks being processed in b -+ public static final int getEntityCount(WorldServer server, Class oClass) { -+ int i = 0; -+ for (Long coord : b.keySet()) { -+ int x = LongHash.msw(coord); -+ int z = LongHash.lsw(coord); -+ if (!server.chunkProviderServer.unloadQueue.contains(x,z) && server.isChunkLoaded(x, z)) { -+ for (List entitySlice : server.getChunkAt(x, z).entitySlices) { -+ for (Entity entity : entitySlice) { -+ if (oClass.isAssignableFrom(entity.getClass())) { -+ ++i; -+ } -+ } -+ } -+ } -+ } -+ return i; -+ } -+ // Spigot end -+ - public static final int spawnEntities(WorldServer worldserver, boolean flag, boolean flag1, boolean flag2) { - if (!flag && !flag1) { - return 0; -@@ -34,13 +55,24 @@ public final class SpawnerCreature { +@@ -34,13 +35,24 @@ public final class SpawnerCreature { int i; int j; @@ -70,7 +43,7 @@ index b3e2818..6362a37 100644 for (int l = -b0; l <= b0; ++l) { for (int i1 = -b0; i1 <= b0; ++i1) { -@@ -88,13 +120,15 @@ public final class SpawnerCreature { +@@ -88,13 +100,15 @@ public final class SpawnerCreature { if (limit == 0) { continue; } @@ -78,7 +51,7 @@ index b3e2818..6362a37 100644 // CraftBukkit end - if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && (!enumcreaturetype.e() || flag2) && worldserver.a(enumcreaturetype.a()) <= limit * b.size() / 256) { // CraftBukkit - use per-world limits -+ if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && (!enumcreaturetype.e() || flag2) && (mobcnt = getEntityCount(worldserver, enumcreaturetype.a())) <= limit * b.size() / 256) { // CraftBukkit - use per-world limits and use all loaded chunks ++ if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && (!enumcreaturetype.e() || flag2) && (mobcnt = worldserver.a(enumcreaturetype.a())) <= limit * b.size() / 256) { // CraftBukkit - use per-world limits and use all loaded chunks Iterator iterator = b.keySet().iterator(); + int moblimit = (limit * b.size() / 256) - mobcnt + 1; // CraftBukkit - up to 1 more than limit @@ -88,7 +61,7 @@ index b3e2818..6362a37 100644 // CraftBukkit start long key = ((Long) iterator.next()).longValue(); -@@ -158,6 +192,12 @@ public final class SpawnerCreature { +@@ -158,6 +172,12 @@ public final class SpawnerCreature { a(entityliving, worldserver, f, f1, f2); worldserver.addEntity(entityliving, SpawnReason.NATURAL); // CraftBukkit end @@ -102,5 +75,5 @@ index b3e2818..6362a37 100644 continue label110; } -- -1.8.2.1 +1.7.11.msysgit.0 diff --git a/CraftBukkit-Patches/0040-Save-entity-counts-for-randomly-spawned-creatures-to.patch b/CraftBukkit-Patches/0040-Save-entity-counts-for-randomly-spawned-creatures-to.patch index 8b1ff0e76f..d573bb0a35 100644 --- a/CraftBukkit-Patches/0040-Save-entity-counts-for-randomly-spawned-creatures-to.patch +++ b/CraftBukkit-Patches/0040-Save-entity-counts-for-randomly-spawned-creatures-to.patch @@ -1,83 +1,73 @@ -From 42fcf69ddb25ec9aebbd6bbd45e552870b0373a9 Mon Sep 17 00:00:00 2001 +From b59089bc2de520bc295712f1320a568dfb218bdd Mon Sep 17 00:00:00 2001 From: Ammar Askar Date: Sat, 20 Apr 2013 12:26:20 +0500 Subject: [PATCH] Save entity counts for randomly spawned creatures to avoid - repeatedly traversing over the entity slices + repeatedly traversing over the entity slices and chunks ---- - src/main/java/net/minecraft/server/Chunk.java | 16 ++++++++++++++++ - src/main/java/net/minecraft/server/SpawnerCreature.java | 10 ++-------- - 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 7f1c155..11e1a4e 100644 +index 7f1c155..7dd931c 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -9,6 +9,7 @@ import java.util.Map; - import java.util.Random; - - import org.bukkit.Bukkit; // CraftBukkit -+import gnu.trove.map.hash.TObjectIntHashMap; // Spigot - - public class Chunk { - -@@ -33,6 +34,7 @@ public class Chunk { - public int p; - private int u; - boolean q; -+ protected TObjectIntHashMap entityCount = new TObjectIntHashMap(); // Spigot - - public Chunk(World world, int i, int j) { - this.sections = new ChunkSection[16]; -@@ -560,6 +562,13 @@ public class Chunk { +@@ -560,6 +560,13 @@ public class Chunk { entity.ak = k; entity.al = this.z; this.entitySlices[k].add(entity); + // Spigot start - increment creature type count + for (EnumCreatureType creatureType : EnumCreatureType.values()) { + if (creatureType.a().isAssignableFrom(entity.getClass())) { -+ this.entityCount.adjustOrPutValue(creatureType.a(), 1, 1); ++ world.entityCount.adjustOrPutValue(creatureType.a(), 1, 1); + } + } + // Spigot end } public void b(Entity entity) { -@@ -576,6 +585,13 @@ public class Chunk { +@@ -576,6 +583,13 @@ public class Chunk { } this.entitySlices[i].remove(entity); + // Spigot start - decrement creature type count + for (EnumCreatureType creatureType : EnumCreatureType.values()) { + if (creatureType.a().isAssignableFrom(entity.getClass())) { -+ this.entityCount.adjustValue(creatureType.a(), -1); ++ world.entityCount.adjustValue(creatureType.a(), -1); + } + } + // Spigot end } public boolean d(int i, int j, int k) { -diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java -index 6362a37..2c3b94d 100644 ---- a/src/main/java/net/minecraft/server/SpawnerCreature.java -+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java -@@ -33,14 +33,8 @@ public final class SpawnerCreature { - for (Long coord : b.keySet()) { - int x = LongHash.msw(coord); - int z = LongHash.lsw(coord); -- if (!server.chunkProviderServer.unloadQueue.contains(x,z) && server.isChunkLoaded(x, z)) { -- for (List entitySlice : server.getChunkAt(x, z).entitySlices) { -- for (Entity entity : entitySlice) { -- if (oClass.isAssignableFrom(entity.getClass())) { -- ++i; -- } -- } -- } -+ if (!server.chunkProviderServer.unloadQueue.contains(coord) && server.isChunkLoaded(x, z)) { -+ i += server.getChunkAt(x, z).entityCount.get(oClass); - } +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 7e10318..3b23a58 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -76,6 +76,7 @@ public abstract class World implements IBlockAccess { + int[] H; + public boolean isStatic; + // Spigot start ++ protected gnu.trove.map.hash.TObjectIntHashMap entityCount = new gnu.trove.map.hash.TObjectIntHashMap(); + + public static long chunkToKey(int x, int z) { + long k = ((((long)x) & 0xFFFF0000L) << 16) | ((((long)x) & 0x0000FFFFL) << 0); +@@ -2456,6 +2457,9 @@ public abstract class World implements IBlockAccess { + } + + public int a(Class oclass) { ++ // Spigot start - commented out inefficient chunk traversing in favour of keeping entity counts in a map ++ return this.entityCount.get(oclass); ++ /* + int i = 0; + + for (int j = 0; j < this.entityList.size(); ++j) { +@@ -2467,6 +2471,8 @@ public abstract class World implements IBlockAccess { } + return i; ++ */ ++ // Spigot end + } + + public void a(List list) { -- 1.7.11.msysgit.0