-
-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
060b346
commit d166b82
Showing
2 changed files
with
187 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: violetc <[email protected]> | ||
Date: Thu, 20 Jul 2023 16:09:56 +0800 | ||
Subject: [PATCH] Use optimized collection | ||
|
||
This patch is Powered by Gale(https://github.com/GaleMC/Gale) | ||
|
||
diff --git a/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java b/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java | ||
index 50a9f33aa31e9273c7c52d4bb2b02f0f884f7ba5..53021c7d173b3c067322e356fead0949aac3fc60 100644 | ||
--- a/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java | ||
+++ b/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java | ||
@@ -13,7 +13,7 @@ import java.util.Map; | ||
import java.util.stream.Collectors; | ||
|
||
public class ClassInstanceMultiMap<T> extends AbstractCollection<T> { | ||
- private final Map<Class<?>, List<T>> byClass = Maps.newHashMap(); | ||
+ private final Map<Class<?>, List<T>> byClass = top.leavesmc.leaves.LeavesConfig.useOptimizedCollection ? new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(2) : Maps.newHashMap(); // Leaves - replace class map with optimized collection | ||
private final Class<T> baseClass; | ||
private final List<T> allInstances = Lists.newArrayList(); | ||
|
||
@@ -58,7 +58,7 @@ public class ClassInstanceMultiMap<T> extends AbstractCollection<T> { | ||
if (!this.baseClass.isAssignableFrom(type)) { | ||
throw new IllegalArgumentException("Don't know how to search for " + type); | ||
} else { | ||
- List<? extends T> list = this.byClass.computeIfAbsent(type, (typeClass) -> { | ||
+ List list = this.byClass.computeIfAbsent(type, (typeClass) -> { // Leaves - dev fix | ||
return this.allInstances.stream().filter(typeClass::isInstance).collect(Collectors.toList()); | ||
}); | ||
return Collections.unmodifiableCollection(list); | ||
diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java | ||
index 53c094c8a674b2842009727569e7e1f6ac6510b7..c5b0ef5fa68e10987e75535fe18450930966ba24 100644 | ||
--- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java | ||
+++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java | ||
@@ -20,8 +20,10 @@ import org.slf4j.Logger; | ||
|
||
public class AttributeMap { | ||
private static final Logger LOGGER = LogUtils.getLogger(); | ||
- private final Map<Attribute, AttributeInstance> attributes = Maps.newHashMap(); | ||
- private final Set<AttributeInstance> dirtyAttributes = Sets.newHashSet(); | ||
+ // Leaves start - replace AI attributes with optimized collections | ||
+ private final Map<Attribute, AttributeInstance> attributes = top.leavesmc.leaves.LeavesConfig.useOptimizedCollection ? new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(0) : Maps.newHashMap(); | ||
+ private final Set<AttributeInstance> dirtyAttributes = top.leavesmc.leaves.LeavesConfig.useOptimizedCollection ? new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0) : Sets.newHashSet(); | ||
+ // Leaves end - replace AI attributes with optimized collections | ||
private final AttributeSupplier supplier; | ||
private final java.util.function.Function<Attribute, AttributeInstance> createInstance; // Leaves - reduce entity allocations | ||
|
||
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 b738ee2d3801fadfd09313f05ae24593e56b0ec6..2d1abb9518795875b3719efe91e60508c2c73163 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 | ||
@@ -28,7 +28,7 @@ public class GoalSelector { | ||
} | ||
}; | ||
private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap<>(Goal.Flag.class); | ||
- private final Set<WrappedGoal> availableGoals = Sets.newLinkedHashSet(); | ||
+ private final Set<WrappedGoal> availableGoals = top.leavesmc.leaves.LeavesConfig.useOptimizedCollection ? new it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet<>() : Sets.newLinkedHashSet(); // Leaves - replace AI goal set with optimized collection | ||
private final Supplier<ProfilerFiller> profiler; | ||
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 | ||
diff --git a/src/main/java/net/minecraft/world/level/GameRules.java b/src/main/java/net/minecraft/world/level/GameRules.java | ||
index 6fa00d9239546aa82b9e92e25a33103868084c38..5d50d9d2700a8943105301ef0ac467e49ce86a02 100644 | ||
--- a/src/main/java/net/minecraft/world/level/GameRules.java | ||
+++ b/src/main/java/net/minecraft/world/level/GameRules.java | ||
@@ -127,7 +127,7 @@ public class GameRules { | ||
} | ||
|
||
private GameRules(Map<GameRules.Key<?>, GameRules.Value<?>> rules) { | ||
- this.rules = rules; | ||
+ this.rules = top.leavesmc.leaves.LeavesConfig.useOptimizedCollection ? new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(rules) : rules; // Leaves - replace game rules map with optimized collection | ||
|
||
// Paper start | ||
int arraySize = rules.keySet().stream().mapToInt(key -> key.gameRuleIndex).max().orElse(-1) + 1; | ||
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java | ||
index 96b9d47aa3720491424c35c9e73fc996bfc8cd20..b87ce8e774e1030de8986067a308505c735a494d 100644 | ||
--- a/src/main/java/net/minecraft/world/level/block/Block.java | ||
+++ b/src/main/java/net/minecraft/world/level/block/Block.java | ||
@@ -61,6 +61,7 @@ import net.minecraft.world.phys.shapes.BooleanOp; | ||
import net.minecraft.world.phys.shapes.Shapes; | ||
import net.minecraft.world.phys.shapes.VoxelShape; | ||
import org.slf4j.Logger; | ||
+import top.leavesmc.leaves.lithium.common.util.collections.Object2BooleanCacheTable; | ||
|
||
public class Block extends BlockBehaviour implements ItemLike { | ||
|
||
@@ -72,6 +73,12 @@ public class Block extends BlockBehaviour implements ItemLike { | ||
return !Shapes.joinIsNotEmpty(Shapes.block(), voxelshape, BooleanOp.NOT_SAME); | ||
} | ||
}); | ||
+ // Leaves start - replace shape full block cache with hashtable | ||
+ private static final Object2BooleanCacheTable<VoxelShape> LITHIUM_SHAPE_FULL_BLOCK_CACHE = new Object2BooleanCacheTable<>( | ||
+ 1536, | ||
+ shape -> !Shapes.joinIsNotEmpty(Shapes.block(), shape, BooleanOp.NOT_SAME) | ||
+ ); | ||
+ // Leaves end - replace shape full block cache with hashtable | ||
public static final int UPDATE_NEIGHBORS = 1; | ||
public static final int UPDATE_CLIENTS = 2; | ||
public static final int UPDATE_INVISIBLE = 4; | ||
@@ -277,7 +284,13 @@ public class Block extends BlockBehaviour implements ItemLike { | ||
} | ||
|
||
public static boolean isShapeFullBlock(VoxelShape shape) { | ||
- return (Boolean) Block.SHAPE_FULL_BLOCK_CACHE.getUnchecked(shape); | ||
+ // Leaves start - replace shape full block cache with hashtable | ||
+ if (!top.leavesmc.leaves.LeavesConfig.useOptimizedCollection) { | ||
+ return (Boolean) Block.SHAPE_FULL_BLOCK_CACHE.getUnchecked(shape); | ||
+ } else { | ||
+ return Block.LITHIUM_SHAPE_FULL_BLOCK_CACHE.get(shape); | ||
+ } | ||
+ // Leaves end - replace shape full block cache with hashtable | ||
} | ||
|
||
public boolean propagatesSkylightDown(BlockState state, BlockGetter world, BlockPos pos) { | ||
diff --git a/src/main/java/top/leavesmc/leaves/lithium/common/util/collections/Object2BooleanCacheTable.java b/src/main/java/top/leavesmc/leaves/lithium/common/util/collections/Object2BooleanCacheTable.java | ||
new file mode 100644 | ||
index 0000000000000000000000000000000000000000..45232059b188b5f072e28c4cdf05929005972220 | ||
--- /dev/null | ||
+++ b/src/main/java/top/leavesmc/leaves/lithium/common/util/collections/Object2BooleanCacheTable.java | ||
@@ -0,0 +1,62 @@ | ||
+package top.leavesmc.leaves.lithium.common.util.collections; | ||
+ | ||
+import it.unimi.dsi.fastutil.HashCommon; | ||
+import net.minecraft.util.Mth; | ||
+ | ||
+import java.util.function.Predicate; | ||
+ | ||
+// Powered by Gale(https://github.com/GaleMC/Gale) | ||
+ | ||
+/** | ||
+ * A lossy hashtable implementation that stores a mapping between an object and a boolean. | ||
+ * <p> | ||
+ * Any hash collisions will result in an overwrite: this is safe because the correct value can always be recomputed, | ||
+ * given that the given operator is deterministic. | ||
+ * <p> | ||
+ * This implementation is safe to use from multiple threads | ||
+ */ | ||
+public final class Object2BooleanCacheTable<T> { | ||
+ | ||
+ private final int mask; | ||
+ private final Node<T>[] nodes; | ||
+ private final Predicate<T> operator; | ||
+ | ||
+ @SuppressWarnings("unchecked") | ||
+ public Object2BooleanCacheTable(int capacity, Predicate<T> operator) { | ||
+ int capacity1 = Mth.smallestEncompassingPowerOfTwo(capacity); | ||
+ this.mask = capacity1 - 1; | ||
+ this.nodes = (Node<T>[]) new Node[capacity1]; | ||
+ this.operator = operator; | ||
+ } | ||
+ | ||
+ private static <T> int hash(T key) { | ||
+ return HashCommon.mix(key.hashCode()); | ||
+ } | ||
+ | ||
+ public boolean get(T key) { | ||
+ int idx = hash(key) & this.mask; | ||
+ | ||
+ Node<T> node = this.nodes[idx]; | ||
+ if (node != null && key.equals(node.key)) { | ||
+ return node.value; | ||
+ } | ||
+ | ||
+ boolean test = this.operator.test(key); | ||
+ this.nodes[idx] = new Node<>(key, test); | ||
+ | ||
+ return test; | ||
+ } | ||
+ | ||
+ static class Node<T> { | ||
+ | ||
+ final T key; | ||
+ final boolean value; | ||
+ | ||
+ Node(T key, boolean value) { | ||
+ this.key = key; | ||
+ this.value = value; | ||
+ } | ||
+ | ||
+ } | ||
+ | ||
+} |