diff options
author | Kyle Wood <[email protected]> | 2021-04-24 17:01:33 -0500 |
---|---|---|
committer | Kyle Wood <[email protected]> | 2021-04-25 18:37:43 -0500 |
commit | 3093b81fee3064603c368ab934eddf66ce304433 (patch) | |
tree | cb99f05b5f31de92c41af4cc40b4bef5f3cbf573 /Spigot-Server-Patches-Unmapped/0435-Remove-streams-from-Mob-AI-System.patch | |
parent | 1af696a05d21cbdd7b5a7170f95598c013257588 (diff) | |
download | Paper-3093b81fee3064603c368ab934eddf66ce304433.tar.gz Paper-3093b81fee3064603c368ab934eddf66ce304433.zip |
Move patches
Diffstat (limited to 'Spigot-Server-Patches-Unmapped/0435-Remove-streams-from-Mob-AI-System.patch')
-rw-r--r-- | Spigot-Server-Patches-Unmapped/0435-Remove-streams-from-Mob-AI-System.patch | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/Spigot-Server-Patches-Unmapped/0435-Remove-streams-from-Mob-AI-System.patch b/Spigot-Server-Patches-Unmapped/0435-Remove-streams-from-Mob-AI-System.patch new file mode 100644 index 0000000000..4937798620 --- /dev/null +++ b/Spigot-Server-Patches-Unmapped/0435-Remove-streams-from-Mob-AI-System.patch @@ -0,0 +1,253 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf <[email protected]> +Date: Mon, 6 Apr 2020 17:53:29 -0700 +Subject: [PATCH] Remove streams from Mob AI System + +The streams hurt performance and allocate tons of garbage, so +replace them with the standard iterator. + +Also optimise the stream.anyMatch statement to move to a bitset +where we can replace the call with a single bitwise operation. + +diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoal.java +index b505c23c57a4b84faf5906c6295455b4720c4426..5c32cbe81c47fcb9ae347faa6fc007c5d28d79bf 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoal.java ++++ b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoal.java +@@ -1,10 +1,12 @@ + package net.minecraft.world.entity.ai.goal; + ++import com.destroystokyo.paper.util.set.OptimizedSmallEnumSet; // Paper - remove streams from pathfindergoalselector + import java.util.EnumSet; + + public abstract class PathfinderGoal { + +- private final EnumSet<PathfinderGoal.Type> a = EnumSet.noneOf(PathfinderGoal.Type.class); ++ private final EnumSet<PathfinderGoal.Type> a = EnumSet.noneOf(PathfinderGoal.Type.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. ++ private final OptimizedSmallEnumSet<Type> goalTypes = new OptimizedSmallEnumSet<>(PathfinderGoal.Type.class); // Paper - remove streams from pathfindergoalselector + + public PathfinderGoal() {} + +@@ -28,16 +30,20 @@ public abstract class PathfinderGoal { + public void e() {} + + public void a(EnumSet<PathfinderGoal.Type> enumset) { +- this.a.clear(); +- this.a.addAll(enumset); ++ // Paper start - remove streams from pathfindergoalselector ++ this.goalTypes.clear(); ++ this.goalTypes.addAllUnchecked(enumset); ++ // Paper end - remove streams from pathfindergoalselector + } + + public String toString() { + return this.getClass().getSimpleName(); + } + +- public EnumSet<PathfinderGoal.Type> i() { +- return this.a; ++ // Paper start - remove streams from pathfindergoalselector ++ public com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<PathfinderGoal.Type> getGoalTypes() { ++ return this.goalTypes; ++ // Paper end - remove streams from pathfindergoalselector + } + + public static enum Type { +diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalSelector.java +index 8c234c09a4d9ada83e36e3cdbcc1f2f5c6202f28..385cd079e264a7e66e91ab3b70b90afb59688dcd 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalSelector.java ++++ b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalSelector.java +@@ -1,8 +1,10 @@ + package net.minecraft.world.entity.ai.goal; + ++import com.destroystokyo.paper.util.set.OptimizedSmallEnumSet; // Paper - remove streams from pathfindergoalselector + import com.google.common.collect.Sets; + import java.util.EnumMap; + import java.util.EnumSet; ++import java.util.Iterator; // Paper - remove streams from pathfindergoalselector + import java.util.Map; + import java.util.Set; + import java.util.function.Supplier; +@@ -28,7 +30,8 @@ public class PathfinderGoalSelector { + private final Map<PathfinderGoal.Type, PathfinderGoalWrapped> c = new EnumMap(PathfinderGoal.Type.class); + private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet(); private Set<PathfinderGoalWrapped> getTasks() { return d; }// Paper - OBFHELPER + private final Supplier<GameProfilerFiller> e; +- private final EnumSet<PathfinderGoal.Type> f = EnumSet.noneOf(PathfinderGoal.Type.class); ++ private final EnumSet<PathfinderGoal.Type> f = EnumSet.noneOf(PathfinderGoal.Type.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. ++ private final OptimizedSmallEnumSet<PathfinderGoal.Type> goalTypes = new OptimizedSmallEnumSet<>(PathfinderGoal.Type.class); // Paper - remove streams from pathfindergoalselector + private int g = 3;private int getTickRate() { return g; } // Paper - OBFHELPER + private int curRate;private int getCurRate() { return curRate; } private void incRate() { this.curRate++; } // Paper TODO + +@@ -56,35 +59,38 @@ public class PathfinderGoalSelector { + // Paper end + + public void a(PathfinderGoal pathfindergoal) { +- this.d.stream().filter((pathfindergoalwrapped) -> { +- return pathfindergoalwrapped.j() == pathfindergoal; +- }).filter(PathfinderGoalWrapped::g).forEach(PathfinderGoalWrapped::d); +- this.d.removeIf((pathfindergoalwrapped) -> { +- return pathfindergoalwrapped.j() == pathfindergoal; +- }); ++ // Paper start - remove streams from pathfindergoalselector ++ for (Iterator<PathfinderGoalWrapped> iterator = this.d.iterator(); iterator.hasNext();) { ++ PathfinderGoalWrapped goalWrapped = iterator.next(); ++ if (goalWrapped.j() != pathfindergoal) { ++ continue; ++ } ++ if (goalWrapped.g()) { ++ goalWrapped.d(); ++ } ++ iterator.remove(); ++ } ++ // Paper end - remove streams from pathfindergoalselector + } + ++ private static final PathfinderGoal.Type[] PATHFINDER_GOAL_TYPES = PathfinderGoal.Type.values(); // Paper - remove streams from pathfindergoalselector ++ + public void doTick() { + GameProfilerFiller gameprofilerfiller = (GameProfilerFiller) this.e.get(); + + gameprofilerfiller.enter("goalCleanup"); +- this.d().filter((pathfindergoalwrapped) -> { +- boolean flag; +- +- if (pathfindergoalwrapped.g()) { +- Stream stream = pathfindergoalwrapped.i().stream(); +- EnumSet enumset = this.f; +- +- this.f.getClass(); +- if (!stream.anyMatch(enumset::contains) && pathfindergoalwrapped.b()) { +- flag = false; +- return flag; +- } ++ // Paper start - remove streams from pathfindergoalselector ++ for (Iterator<PathfinderGoalWrapped> iterator = this.d.iterator(); iterator.hasNext();) { ++ PathfinderGoalWrapped wrappedGoal = iterator.next(); ++ if (!wrappedGoal.g()) { ++ continue; + } +- +- flag = true; +- return flag; +- }).forEach(PathfinderGoal::d); ++ if (!this.goalTypes.hasCommonElements(wrappedGoal.getGoalTypes()) && wrappedGoal.b()) { ++ continue; ++ } ++ wrappedGoal.d(); ++ } ++ // Paper end - remove streams from pathfindergoalselector + this.c.forEach((pathfindergoal_type, pathfindergoalwrapped) -> { + if (!pathfindergoalwrapped.g()) { + this.c.remove(pathfindergoal_type); +@@ -93,30 +99,58 @@ public class PathfinderGoalSelector { + }); + gameprofilerfiller.exit(); + gameprofilerfiller.enter("goalUpdate"); +- this.d.stream().filter((pathfindergoalwrapped) -> { +- return !pathfindergoalwrapped.g(); +- }).filter((pathfindergoalwrapped) -> { +- Stream stream = pathfindergoalwrapped.i().stream(); +- EnumSet enumset = this.f; +- +- this.f.getClass(); +- return stream.noneMatch(enumset::contains); +- }).filter((pathfindergoalwrapped) -> { +- return pathfindergoalwrapped.i().stream().allMatch((pathfindergoal_type) -> { +- return ((PathfinderGoalWrapped) this.c.getOrDefault(pathfindergoal_type, PathfinderGoalSelector.b)).a(pathfindergoalwrapped); +- }); +- }).filter(PathfinderGoalWrapped::a).forEach((pathfindergoalwrapped) -> { +- pathfindergoalwrapped.i().forEach((pathfindergoal_type) -> { +- PathfinderGoalWrapped pathfindergoalwrapped1 = (PathfinderGoalWrapped) this.c.getOrDefault(pathfindergoal_type, PathfinderGoalSelector.b); +- +- pathfindergoalwrapped1.d(); +- this.c.put(pathfindergoal_type, pathfindergoalwrapped); +- }); +- pathfindergoalwrapped.c(); +- }); ++ // Paper start - remove streams from pathfindergoalselector ++ goal_update_loop: for (Iterator<PathfinderGoalWrapped> iterator = this.d.iterator(); iterator.hasNext();) { ++ PathfinderGoalWrapped wrappedGoal = iterator.next(); ++ if (wrappedGoal.g()) { ++ continue; ++ } ++ ++ OptimizedSmallEnumSet<PathfinderGoal.Type> wrappedGoalSet = wrappedGoal.getGoalTypes(); ++ ++ if (this.goalTypes.hasCommonElements(wrappedGoalSet)) { ++ continue; ++ } ++ ++ long iterator1 = wrappedGoalSet.getBackingSet(); ++ int wrappedGoalSize = wrappedGoalSet.size(); ++ for (int i = 0; i < wrappedGoalSize; ++i) { ++ PathfinderGoal.Type type = PATHFINDER_GOAL_TYPES[Long.numberOfTrailingZeros(iterator1)]; ++ iterator1 ^= com.destroystokyo.paper.util.math.IntegerUtil.getTrailingBit(iterator1); ++ PathfinderGoalWrapped wrapped = this.c.getOrDefault(type, PathfinderGoalSelector.b); ++ if (!wrapped.a(wrappedGoal)) { ++ continue goal_update_loop; ++ } ++ } ++ ++ if (!wrappedGoal.a()) { ++ continue; ++ } ++ ++ iterator1 = wrappedGoalSet.getBackingSet(); ++ wrappedGoalSize = wrappedGoalSet.size(); ++ for (int i = 0; i < wrappedGoalSize; ++i) { ++ PathfinderGoal.Type type = PATHFINDER_GOAL_TYPES[Long.numberOfTrailingZeros(iterator1)]; ++ iterator1 ^= com.destroystokyo.paper.util.math.IntegerUtil.getTrailingBit(iterator1); ++ PathfinderGoalWrapped wrapped = this.c.getOrDefault(type, PathfinderGoalSelector.b); ++ ++ wrapped.d(); ++ this.c.put(type, wrappedGoal); ++ } ++ ++ wrappedGoal.c(); ++ } ++ // Paper end - remove streams from pathfindergoalselector + gameprofilerfiller.exit(); + gameprofilerfiller.enter("goalTick"); +- this.d().forEach(PathfinderGoalWrapped::e); ++ // Paper start - remove streams from pathfindergoalselector ++ for (Iterator<PathfinderGoalWrapped> iterator = this.d.iterator(); iterator.hasNext();) { ++ PathfinderGoalWrapped wrappedGoal = iterator.next(); ++ if (wrappedGoal.g()) { ++ wrappedGoal.e(); ++ } ++ } ++ // Paper end - remove streams from pathfindergoalselector + gameprofilerfiller.exit(); + } + +@@ -125,11 +159,11 @@ public class PathfinderGoalSelector { + } + + public void a(PathfinderGoal.Type pathfindergoal_type) { +- this.f.add(pathfindergoal_type); ++ this.goalTypes.addUnchecked(pathfindergoal_type); // Paper - remove streams from pathfindergoalselector + } + + public void b(PathfinderGoal.Type pathfindergoal_type) { +- this.f.remove(pathfindergoal_type); ++ this.goalTypes.removeUnchecked(pathfindergoal_type); // Paper - remove streams from pathfindergoalselector + } + + public void a(PathfinderGoal.Type pathfindergoal_type, boolean flag) { +diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalWrapped.java b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalWrapped.java +index 7bb531e47668cf445083c4dedb03ccafe6a9c96b..8c8e39d35fb56aa6cf7d456adab01dff5d13a60d 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalWrapped.java ++++ b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalWrapped.java +@@ -59,9 +59,10 @@ public class PathfinderGoalWrapped extends PathfinderGoal { + this.a.a(enumset); + } + +- @Override +- public EnumSet<PathfinderGoal.Type> i() { +- return this.a.i(); ++ // Paper start - remove streams from pathfindergoalselector ++ public com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<PathfinderGoal.Type> getGoalTypes() { ++ return this.a.getGoalTypes(); ++ // Paper end - remove streams from pathfindergoalselector + } + + public boolean isRunning() { return this.g(); } // Paper - OBFHELPER |