Paper/patches/server/0999-Optimize-GoalSelector-Goal.Flag-Set-operations.patch
Nassim Jahnke 31699ae9a8
Updated Upstream (Bukkit/CraftBukkit) (#10242)
* Updated Upstream (Bukkit/CraftBukkit)

Upstream has released updates that appear to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
a6a9d2a4 Remove some old ApiStatus.Experimental annotations
be72314c SPIGOT-7300, PR-829: Add new DamageSource API providing enhanced information about entity damage
b252cf05 SPIGOT-7576, PR-970: Add methods in MushroomCow to change stew effects
b1c689bd PR-902: Add Server#isLoggingIPs to get log-ips configuration
08f86d1c PR-971: Add Player methods for client-side potion effects
2e3024a9 PR-963: Add API for in-world structures
a23292a7 SPIGOT-7530, PR-948: Improve Resource Pack API with new 1.20.3 functionality
1851857b SPIGOT-3071, PR-969: Add entity spawn method with spawn reason
cde4c52a SPIGOT-5553, PR-964: Add EntityKnockbackEvent

CraftBukkit Changes:
38fd4bd50 Fix accidentally renamed internal damage method
80f0ce4be SPIGOT-7300, PR-1180: Add new DamageSource API providing enhanced information about entity damage
7e43f3b16 SPIGOT-7581: Fix typo in BlockMushroom
ea14b7d90 SPIGOT-7576, PR-1347: Add methods in MushroomCow to change stew effects
4c687f243 PR-1259: Add Server#isLoggingIPs to get log-ips configuration
22a541a29 Improve support for per-world game rules
cb7dccce2 PR-1348: Add Player methods for client-side potion effects
b8d6109f0 PR-1335: Add API for in-world structures
4398a1b5b SPIGOT-7577: Make CraftWindCharge#explode discard the entity
e74107678 Fix Crafter maximum stack size
0bb0f4f6a SPIGOT-7530, PR-1314: Improve Resource Pack API with new 1.20.3 functionality
4949f556d SPIGOT-3071, PR-1345: Add entity spawn method with spawn reason
20ac73ca2 PR-1353: Fix Structure#place not working as documented with 0 palette
3c1b77871 SPIGOT-6911, PR-1349: Change max book length in CraftMetaBook
333701839 SPIGOT-7572: Bee nests generated without bees
f48f4174c SPIGOT-5553, PR-1336: Add EntityKnockbackEvent
2024-02-11 22:28:00 +01:00

181 lines
9.4 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 6 Apr 2020 17:53:29 -0700
Subject: [PATCH] Optimize GoalSelector Goal.Flag Set operations
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/Goal.java b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
index 16f9a98b8a939e5ca7e2dc04f87134a7ed66736b..dd423302b1baa64ef86ded87a29659342e28c142 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
@@ -4,7 +4,16 @@ import java.util.EnumSet;
import net.minecraft.util.Mth;
public abstract class Goal {
- private final EnumSet<Goal.Flag> flags = EnumSet.noneOf(Goal.Flag.class);
+ private final EnumSet<Goal.Flag> flags = EnumSet.noneOf(Goal.Flag.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 com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<net.minecraft.world.entity.ai.goal.Goal.Flag> goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector
+
+ // Paper start - remove streams from pathfindergoalselector; make sure types are not empty
+ public Goal() {
+ if (this.goalTypes.size() == 0) {
+ this.goalTypes.add(Flag.UNKNOWN_BEHAVIOR);
+ }
+ }
+ // Paper end - remove streams from pathfindergoalselector
public abstract boolean canUse();
@@ -30,8 +39,13 @@ public abstract class Goal {
}
public void setFlags(EnumSet<Goal.Flag> controls) {
- this.flags.clear();
- this.flags.addAll(controls);
+ // Paper start - remove streams from pathfindergoalselector
+ this.goalTypes.clear();
+ this.goalTypes.addAll(controls);
+ if (this.goalTypes.size() == 0) {
+ this.goalTypes.add(Flag.UNKNOWN_BEHAVIOR);
+ }
+ // Paper end - remove streams from pathfindergoalselector
}
@Override
@@ -39,8 +53,10 @@ public abstract class Goal {
return this.getClass().getSimpleName();
}
- public EnumSet<Goal.Flag> getFlags() {
- return this.flags;
+ // Paper start - remove streams from pathfindergoalselector
+ public com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<Goal.Flag> getFlags() {
+ return this.goalTypes;
+ // Paper end - remove streams from pathfindergoalselector
}
protected int adjustedTickDelay(int ticks) {
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
index e5995d0db5dcfba59a873ff439601894fdacd556..676f5485a4ca9252e911213dcda8d51776b637b6 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
@@ -30,10 +30,12 @@ public class GoalSelector {
private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap<>(Goal.Flag.class);
private final Set<WrappedGoal> availableGoals = Sets.newLinkedHashSet();
private final Supplier<ProfilerFiller> profiler;
- private final EnumSet<Goal.Flag> disabledFlags = EnumSet.noneOf(Goal.Flag.class);
+ private final EnumSet<Goal.Flag> disabledFlags = EnumSet.noneOf(Goal.Flag.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 com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<net.minecraft.world.entity.ai.goal.Goal.Flag> goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector
private int tickCount;
private int newGoalRate = 3;
private int curRate;
+ private static final Goal.Flag[] GOAL_FLAG_VALUES = Goal.Flag.values(); // Paper - remove streams from pathfindergoalselector
public GoalSelector(Supplier<ProfilerFiller> profiler) {
this.profiler = profiler;
@@ -65,26 +67,32 @@ public class GoalSelector {
}
// Paper end
public void removeGoal(Goal goal) {
- this.availableGoals.stream().filter((wrappedGoal) -> {
- return wrappedGoal.getGoal() == goal;
- }).filter(WrappedGoal::isRunning).forEach(WrappedGoal::stop);
- this.availableGoals.removeIf((wrappedGoal) -> {
- return wrappedGoal.getGoal() == goal;
- });
- }
-
- private static boolean goalContainsAnyFlags(WrappedGoal goal, EnumSet<Goal.Flag> controls) {
- for(Goal.Flag flag : goal.getFlags()) {
- if (controls.contains(flag)) {
- return true;
+ // Paper start - remove streams from pathfindergoalselector
+ for (java.util.Iterator<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) {
+ WrappedGoal goalWrapped = iterator.next();
+ if (goalWrapped.getGoal() != goal) {
+ continue;
}
+ if (goalWrapped.isRunning()) {
+ goalWrapped.stop();
+ }
+ iterator.remove();
}
+ // Paper end - remove streams from pathfindergoalselector
+ }
- return false;
+ private static boolean goalContainsAnyFlags(WrappedGoal goal, com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<Goal.Flag> controls) {
+ return goal.getFlags().hasCommonElements(controls); // Paper
}
private static boolean goalCanBeReplacedForAllFlags(WrappedGoal goal, Map<Goal.Flag, WrappedGoal> goalsByControl) {
- for(Goal.Flag flag : goal.getFlags()) {
+ // Paper start
+ long flagIterator = goal.getFlags().getBackingSet();
+ int wrappedGoalSize = goal.getFlags().size();
+ for (int i = 0; i < wrappedGoalSize; ++i) {
+ final Goal.Flag flag = GOAL_FLAG_VALUES[Long.numberOfTrailingZeros(flagIterator)];
+ flagIterator ^= io.papermc.paper.util.IntegerUtil.getTrailingBit(flagIterator);
+ // Paper end
if (!goalsByControl.getOrDefault(flag, NO_GOAL).canBeReplacedBy(goal)) {
return false;
}
@@ -98,7 +106,7 @@ public class GoalSelector {
profilerFiller.push("goalCleanup");
for(WrappedGoal wrappedGoal : this.availableGoals) {
- if (wrappedGoal.isRunning() && (goalContainsAnyFlags(wrappedGoal, this.disabledFlags) || !wrappedGoal.canContinueToUse())) {
+ if (wrappedGoal.isRunning() && (goalContainsAnyFlags(wrappedGoal, this.goalTypes) || !wrappedGoal.canContinueToUse())) {
wrappedGoal.stop();
}
}
@@ -116,8 +124,14 @@ public class GoalSelector {
profilerFiller.push("goalUpdate");
for(WrappedGoal wrappedGoal2 : this.availableGoals) {
- if (!wrappedGoal2.isRunning() && !goalContainsAnyFlags(wrappedGoal2, this.disabledFlags) && goalCanBeReplacedForAllFlags(wrappedGoal2, this.lockedFlags) && wrappedGoal2.canUse()) {
- for(Goal.Flag flag : wrappedGoal2.getFlags()) {
+ // Paper start
+ if (!wrappedGoal2.isRunning() && !goalContainsAnyFlags(wrappedGoal2, this.goalTypes) && goalCanBeReplacedForAllFlags(wrappedGoal2, this.lockedFlags) && wrappedGoal2.canUse()) {
+ long flagIterator = wrappedGoal2.getFlags().getBackingSet();
+ int wrappedGoalSize = wrappedGoal2.getFlags().size();
+ for (int i = 0; i < wrappedGoalSize; ++i) {
+ final Goal.Flag flag = GOAL_FLAG_VALUES[Long.numberOfTrailingZeros(flagIterator)];
+ flagIterator ^= io.papermc.paper.util.IntegerUtil.getTrailingBit(flagIterator);
+ // Paper end
WrappedGoal wrappedGoal3 = this.lockedFlags.getOrDefault(flag, NO_GOAL);
wrappedGoal3.stop();
this.lockedFlags.put(flag, wrappedGoal2);
@@ -157,11 +171,11 @@ public class GoalSelector {
}
public void disableControlFlag(Goal.Flag control) {
- this.disabledFlags.add(control);
+ this.goalTypes.add(control); // Paper - remove streams from pathfindergoalselector
}
public void enableControlFlag(Goal.Flag control) {
- this.disabledFlags.remove(control);
+ this.goalTypes.remove(control); // Paper - remove streams from pathfindergoalselector
}
public void setControlFlag(Goal.Flag control, boolean enabled) {
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java
index 6665ce5f48316e626907e6937d5ef1bc398a7ebd..51deb4455cac055ffa455e4f34aa30858d2fb448 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java
@@ -69,8 +69,10 @@ public class WrappedGoal extends Goal {
}
@Override
- public EnumSet<Goal.Flag> getFlags() {
+ // Paper start - remove streams from pathfindergoalselector
+ public com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<Goal.Flag> getFlags() {
return this.goal.getFlags();
+ // Paper end - remove streams from pathfindergoalselector
}
public boolean isRunning() {