mirror of
https://github.com/BX-Team/DivineMC.git
synced 2025-12-19 14:59:25 +00:00
Moonrise and Level Ticking opts (#33)
* moonrise and ticking opts * additional optimizations * cleanup * update entities patch
This commit is contained in:
@@ -72,7 +72,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val log4jPlugins = sourceSets.create("log4jPlugins") {
|
val log4jPlugins = sourceSets.create("log4jPlugins") {
|
||||||
@@ -156,10 +_,21 @@
|
@@ -156,10 +_,22 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -87,6 +87,7 @@
|
|||||||
+ implementation("com.github.luben:zstd-jni:1.5.7-3")
|
+ implementation("com.github.luben:zstd-jni:1.5.7-3")
|
||||||
+ implementation("org.lz4:lz4-java:1.8.0")
|
+ implementation("org.lz4:lz4-java:1.8.0")
|
||||||
+ implementation("net.openhft:zero-allocation-hashing:0.16")
|
+ implementation("net.openhft:zero-allocation-hashing:0.16")
|
||||||
|
+ implementation("org.agrona:agrona:2.2.4")
|
||||||
+ // DivineMC end - Dependencies
|
+ // DivineMC end - Dependencies
|
||||||
+
|
+
|
||||||
implementation("ca.spottedleaf:concurrentutil:0.0.3")
|
implementation("ca.spottedleaf:concurrentutil:0.0.3")
|
||||||
@@ -175,9 +176,8 @@
|
|||||||
val gitBranch = git.exec(providers, "rev-parse", "--abbrev-ref", "HEAD").get().trim()
|
val gitBranch = git.exec(providers, "rev-parse", "--abbrev-ref", "HEAD").get().trim()
|
||||||
+ val experimental = rootProject.providers.gradleProperty("experimental").get() // DivineMC - Experimental flag
|
+ val experimental = rootProject.providers.gradleProperty("experimental").get() // DivineMC - Experimental flag
|
||||||
attributes(
|
attributes(
|
||||||
- "Main-Class" to "org.bukkit.craftbukkit.Main",
|
"Main-Class" to "org.bukkit.craftbukkit.Main",
|
||||||
- "Implementation-Title" to "Purpur", // Purpur
|
- "Implementation-Title" to "Purpur", // Purpur
|
||||||
+ "Main-Class" to "net.minecraft.server.Main", // DivineMC - Rebrand
|
|
||||||
+ "Implementation-Title" to "DivineMC", // DivineMC - Rebrand
|
+ "Implementation-Title" to "DivineMC", // DivineMC - Rebrand
|
||||||
"Implementation-Version" to implementationVersion,
|
"Implementation-Version" to implementationVersion,
|
||||||
"Implementation-Vendor" to date,
|
"Implementation-Vendor" to date,
|
||||||
@@ -198,12 +198,3 @@
|
|||||||
)
|
)
|
||||||
for (tld in setOf("net", "com", "org")) {
|
for (tld in setOf("net", "com", "org")) {
|
||||||
attributes("$tld/bukkit", "Sealed" to true)
|
attributes("$tld/bukkit", "Sealed" to true)
|
||||||
@@ -328,7 +_,7 @@
|
|
||||||
block: JavaExec.() -> Unit
|
|
||||||
): TaskProvider<JavaExec> = register<JavaExec>(name) {
|
|
||||||
group = "runs"
|
|
||||||
- mainClass.set("org.bukkit.craftbukkit.Main")
|
|
||||||
+ mainClass.set("net.minecraft.server.Main") // DivineMC - Rebrand
|
|
||||||
standardInput = System.`in`
|
|
||||||
workingDir = rootProject.layout.projectDirectory
|
|
||||||
.dir(providers.gradleProperty("paper.runWorkDir").getOrElse("run"))
|
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||||
Date: Sat, 1 Feb 2025 16:05:57 +0300
|
Date: Sat, 1 Feb 2025 16:05:57 +0300
|
||||||
Subject: [PATCH] Optimize entity brain
|
Subject: [PATCH] Optimize entities
|
||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/entity/AgeableMob.java b/net/minecraft/world/entity/AgeableMob.java
|
diff --git a/net/minecraft/world/entity/AgeableMob.java b/net/minecraft/world/entity/AgeableMob.java
|
||||||
index 04875840085541ebfc7014868beec49bb7ab9976..bbfb1de1a03c4208406feb803a2f378db9910556 100644
|
index 04875840085541ebfc7014868beec49bb7ab9976..caea723a4614d3c406dbce71a392716b7442987c 100644
|
||||||
--- a/net/minecraft/world/entity/AgeableMob.java
|
--- a/net/minecraft/world/entity/AgeableMob.java
|
||||||
+++ b/net/minecraft/world/entity/AgeableMob.java
|
+++ b/net/minecraft/world/entity/AgeableMob.java
|
||||||
@@ -125,6 +125,16 @@ public abstract class AgeableMob extends PathfinderMob {
|
@@ -125,6 +125,16 @@ public abstract class AgeableMob extends PathfinderMob {
|
||||||
public void onSyncedDataUpdated(EntityDataAccessor<?> key) {
|
public void onSyncedDataUpdated(EntityDataAccessor<?> key) {
|
||||||
if (DATA_BABY_ID.equals(key)) {
|
if (DATA_BABY_ID.equals(key)) {
|
||||||
this.refreshDimensions();
|
this.refreshDimensions();
|
||||||
+ // DivineMC start - Optimize entity brain
|
+ // DivineMC start - Optimize entities
|
||||||
+ if (isBaby()) {
|
+ if (isBaby()) {
|
||||||
+ org.bxteam.divinemc.util.entity.SensorHelper.enableSensor(this, net.minecraft.world.entity.ai.sensing.SensorType.NEAREST_ADULT, true);
|
+ org.bxteam.divinemc.util.entity.SensorHelper.enableSensor(this, net.minecraft.world.entity.ai.sensing.SensorType.NEAREST_ADULT, true);
|
||||||
+ } else {
|
+ } else {
|
||||||
@@ -21,12 +21,204 @@ index 04875840085541ebfc7014868beec49bb7ab9976..bbfb1de1a03c4208406feb803a2f378d
|
|||||||
+ this.getBrain().setMemory(net.minecraft.world.entity.ai.memory.MemoryModuleType.NEAREST_VISIBLE_ADULT, java.util.Optional.empty());
|
+ this.getBrain().setMemory(net.minecraft.world.entity.ai.memory.MemoryModuleType.NEAREST_VISIBLE_ADULT, java.util.Optional.empty());
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ // DivineMC end - Optimize entity brain
|
+ // DivineMC end - Optimize entities
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onSyncedDataUpdated(key);
|
super.onSyncedDataUpdated(key);
|
||||||
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||||
|
index 989043d73af2c719e6c36ac5d4c35e7d31d3410c..6c7f0c04e94eb3fa2f22d2637a1c2abceb1563f4 100644
|
||||||
|
--- a/net/minecraft/world/entity/Entity.java
|
||||||
|
+++ b/net/minecraft/world/entity/Entity.java
|
||||||
|
@@ -1687,6 +1687,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
|
|
||||||
|
private void checkInsideBlocks(Vec3 vec3, Vec3 vec31, InsideBlockEffectApplier.StepBasedCollector stepBasedCollector, LongSet set) {
|
||||||
|
AABB aabb = this.makeBoundingBox(vec31).deflate(1.0E-5F);
|
||||||
|
+ // DivineMC start - Optimize entities
|
||||||
|
+ final net.minecraft.world.level.chunk.ChunkAccess[] cachedChunk = new net.minecraft.world.level.chunk.ChunkAccess[] { null };
|
||||||
|
+ final long[] lastChunkPos = { Long.MIN_VALUE };
|
||||||
|
+ // DivineMC end - Optimize entities
|
||||||
|
BlockGetter.forEachBlockIntersectedBetween(
|
||||||
|
vec3,
|
||||||
|
vec31,
|
||||||
|
@@ -1695,7 +1699,21 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
|
if (!this.isAlive()) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
- BlockState blockState = this.level().getBlockState(pos);
|
||||||
|
+ // DivineMC start - Optimize entities
|
||||||
|
+ final int chunkX = pos.getX() >> 4;
|
||||||
|
+ final int chunkZ = pos.getZ() >> 4;
|
||||||
|
+ final long chunkLongPos = ((long) chunkZ << 32) | (chunkX & 0xFFFFFFFFL);
|
||||||
|
+ if (lastChunkPos[0] != chunkLongPos) {
|
||||||
|
+ // update cache, this is a different chunk than previous
|
||||||
|
+ lastChunkPos[0] = chunkLongPos;
|
||||||
|
+ cachedChunk[0] = this.level.getChunkIfLoaded(chunkX, chunkZ);
|
||||||
|
+ }
|
||||||
|
+ net.minecraft.world.level.chunk.ChunkAccess chunk = cachedChunk[0];
|
||||||
|
+ if (chunk == null) {
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ BlockState blockState = chunk.getBlockState(pos);
|
||||||
|
+ // DivineMC end - Optimize entities
|
||||||
|
if (blockState.isAir()) {
|
||||||
|
this.debugBlockIntersection(pos, false, false);
|
||||||
|
return true;
|
||||||
|
@@ -1738,6 +1756,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean collidedWithFluid(FluidState fluid, BlockPos pos, Vec3 from, Vec3 to) {
|
||||||
|
+ if (fluid.isEmpty()) return false; // DivineMC - Optimize entities
|
||||||
|
AABB aabb = fluid.getAABB(this.level(), pos);
|
||||||
|
return aabb != null && this.collidedWithShapeMovingFrom(from, to, List.of(aabb));
|
||||||
|
}
|
||||||
|
diff --git a/net/minecraft/world/entity/InsideBlockEffectApplier.java b/net/minecraft/world/entity/InsideBlockEffectApplier.java
|
||||||
|
index a7bc5ead2062504ceac95f603bc1ca8d4290bbfd..533c790ce305043f53c76f03a12676c567118a44 100644
|
||||||
|
--- a/net/minecraft/world/entity/InsideBlockEffectApplier.java
|
||||||
|
+++ b/net/minecraft/world/entity/InsideBlockEffectApplier.java
|
||||||
|
@@ -31,68 +31,115 @@ public interface InsideBlockEffectApplier {
|
||||||
|
|
||||||
|
public static class StepBasedCollector implements InsideBlockEffectApplier {
|
||||||
|
private static final InsideBlockEffectType[] APPLY_ORDER = InsideBlockEffectType.values();
|
||||||
|
- private static final int NO_STEP = -1;
|
||||||
|
- private final Map<InsideBlockEffectType, Consumer<Entity>> effectsInStep = new java.util.EnumMap<>(InsideBlockEffectType.class); // Paper - track position inside effect was triggered on
|
||||||
|
- private final Map<InsideBlockEffectType, List<Consumer<Entity>>> beforeEffectsInStep = Util.makeEnumMap(
|
||||||
|
- InsideBlockEffectType.class, insideBlockEffectType -> new ArrayList<>()
|
||||||
|
- );
|
||||||
|
- private final Map<InsideBlockEffectType, List<Consumer<Entity>>> afterEffectsInStep = Util.makeEnumMap(
|
||||||
|
- InsideBlockEffectType.class, insideBlockEffectType -> new ArrayList<>()
|
||||||
|
- );
|
||||||
|
- private final List<Consumer<Entity>> finalEffects = new ArrayList<>();
|
||||||
|
+ // DivineMC start - Optimize entities
|
||||||
|
+ private final Consumer<Entity>[] effectsInStep = new Consumer[APPLY_ORDER.length];
|
||||||
|
+ private final it.unimi.dsi.fastutil.objects.ObjectArrayList<Consumer<Entity>>[] beforeEffectsInStep = new it.unimi.dsi.fastutil.objects.ObjectArrayList[APPLY_ORDER.length];
|
||||||
|
+ private final it.unimi.dsi.fastutil.objects.ObjectArrayList<Consumer<Entity>>[] afterEffectsInStep = new it.unimi.dsi.fastutil.objects.ObjectArrayList[APPLY_ORDER.length];
|
||||||
|
+ private final it.unimi.dsi.fastutil.objects.ObjectArrayList<Consumer<Entity>> finalEffects = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
|
||||||
|
+ // DivineMC end - Optimize entities
|
||||||
|
private int lastStep = -1;
|
||||||
|
|
||||||
|
- public void advanceStep(int step, net.minecraft.core.BlockPos pos) { // Paper - track position inside effect was triggered on
|
||||||
|
- this.currentBlockPos = pos; // Paper - track position inside effect was triggered on
|
||||||
|
+ // DivineMC start - Optimize entities
|
||||||
|
+ public StepBasedCollector() {
|
||||||
|
+ for (int i = 0; i < APPLY_ORDER.length; i++) {
|
||||||
|
+ beforeEffectsInStep[i] = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(2);
|
||||||
|
+ afterEffectsInStep[i] = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(2);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public void advanceStep(int step, net.minecraft.core.BlockPos pos) {
|
||||||
|
+ this.currentBlockPos = pos;
|
||||||
|
if (this.lastStep != step) {
|
||||||
|
this.lastStep = step;
|
||||||
|
this.flushStep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ // DivineMC end - Optimize entities
|
||||||
|
|
||||||
|
public void applyAndClear(Entity entity) {
|
||||||
|
this.flushStep();
|
||||||
|
|
||||||
|
- for (Consumer<Entity> consumer : this.finalEffects) {
|
||||||
|
+ // DivineMC start - Optimize entities
|
||||||
|
+ List<Consumer<Entity>> effects = this.finalEffects;
|
||||||
|
+ int size = effects.size();
|
||||||
|
+
|
||||||
|
+ if (size == 0) {
|
||||||
|
+ this.lastStep = -1;
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!entity.isAlive()) {
|
||||||
|
+ effects.clear();
|
||||||
|
+ this.lastStep = -1;
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ int i = 0;
|
||||||
|
+ while (i < size - 3) {
|
||||||
|
+ effects.get(i++).accept(entity);
|
||||||
|
+ effects.get(i++).accept(entity);
|
||||||
|
+ effects.get(i++).accept(entity);
|
||||||
|
+ effects.get(i++).accept(entity);
|
||||||
|
if (!entity.isAlive()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- consumer.accept(entity);
|
||||||
|
+ if (entity.isAlive()) {
|
||||||
|
+ for (; i < size; i++) {
|
||||||
|
+ effects.get(i).accept(entity);
|
||||||
|
+ if (!entity.isAlive()) {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
- this.finalEffects.clear();
|
||||||
|
+ effects.clear();
|
||||||
|
+ // DivineMC end - Optimize entities
|
||||||
|
this.lastStep = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void flushStep() {
|
||||||
|
- for (InsideBlockEffectType insideBlockEffectType : APPLY_ORDER) {
|
||||||
|
- List<Consumer<Entity>> list = this.beforeEffectsInStep.get(insideBlockEffectType);
|
||||||
|
- this.finalEffects.addAll(list);
|
||||||
|
- list.clear();
|
||||||
|
- if (this.effectsInStep.remove(insideBlockEffectType) instanceof final Consumer<Entity> recordedEffect) { // Paper - track position inside effect was triggered on - better than null check to avoid diff.
|
||||||
|
- this.finalEffects.add(recordedEffect); // Paper - track position inside effect was triggered on
|
||||||
|
+ // DivineMC start - Optimize entities
|
||||||
|
+ final int len = APPLY_ORDER.length;
|
||||||
|
+ final Consumer<Entity>[] effectArr = this.effectsInStep;
|
||||||
|
+ final List<Consumer<Entity>> finalList = this.finalEffects;
|
||||||
|
+
|
||||||
|
+ for (int i = 0; i < len; i++) {
|
||||||
|
+ List<Consumer<Entity>> beforeList = this.beforeEffectsInStep[i];
|
||||||
|
+ if (!beforeList.isEmpty()) {
|
||||||
|
+ finalList.addAll(beforeList);
|
||||||
|
+ beforeList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
- List<Consumer<Entity>> list1 = this.afterEffectsInStep.get(insideBlockEffectType);
|
||||||
|
- this.finalEffects.addAll(list1);
|
||||||
|
- list1.clear();
|
||||||
|
+ Consumer<Entity> effect = effectArr[i];
|
||||||
|
+ if (effect != null) {
|
||||||
|
+ finalList.add(effect);
|
||||||
|
+ effectArr[i] = null;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ List<Consumer<Entity>> afterList = this.afterEffectsInStep[i];
|
||||||
|
+ if (!afterList.isEmpty()) {
|
||||||
|
+ finalList.addAll(afterList);
|
||||||
|
+ afterList.clear();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+ // DivineMC end - Optimize entities
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(InsideBlockEffectType type) {
|
||||||
|
- this.effectsInStep.put(type, recorded(type)); // Paper - track position inside effect was triggered on
|
||||||
|
+ effectsInStep[type.ordinal()] = recorded(type); // DivineMC - Optimize entities
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runBefore(InsideBlockEffectType type, Consumer<Entity> effect) {
|
||||||
|
- this.beforeEffectsInStep.get(type).add(effect);
|
||||||
|
+ beforeEffectsInStep[type.ordinal()].add(effect); // DivineMC - Optimize entities
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runAfter(InsideBlockEffectType type, Consumer<Entity> effect) {
|
||||||
|
- this.afterEffectsInStep.get(type).add(effect);
|
||||||
|
+ afterEffectsInStep[type.ordinal()].add(effect); // DivineMC - Optimize entities
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paper start - track position inside effect was triggered on
|
||||||
diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java
|
diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java
|
||||||
index 99ced3cb7d3d4c7a80d890689d7585fa9acd17f6..9277b5da6065a5500e40727815083da25b9c9327 100644
|
index 99ced3cb7d3d4c7a80d890689d7585fa9acd17f6..f839b1429c8ef2a630ae3d6e6a02678161aa5858 100644
|
||||||
--- a/net/minecraft/world/entity/ai/Brain.java
|
--- a/net/minecraft/world/entity/ai/Brain.java
|
||||||
+++ b/net/minecraft/world/entity/ai/Brain.java
|
+++ b/net/minecraft/world/entity/ai/Brain.java
|
||||||
@@ -45,16 +45,75 @@ public class Brain<E extends LivingEntity> {
|
@@ -45,16 +45,75 @@ public class Brain<E extends LivingEntity> {
|
||||||
@@ -35,20 +227,20 @@ index 99ced3cb7d3d4c7a80d890689d7585fa9acd17f6..9277b5da6065a5500e40727815083da2
|
|||||||
private static final int SCHEDULE_UPDATE_DELAY = 20;
|
private static final int SCHEDULE_UPDATE_DELAY = 20;
|
||||||
- private final Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = Maps.newHashMap();
|
- private final Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = Maps.newHashMap();
|
||||||
- public final Map<SensorType<? extends Sensor<? super E>>, Sensor<? super E>> sensors = Maps.newLinkedHashMap();
|
- public final Map<SensorType<? extends Sensor<? super E>>, Sensor<? super E>> sensors = Maps.newLinkedHashMap();
|
||||||
+ // DivineMC start - Optimize entity brain
|
+ // DivineMC start - Optimize entities
|
||||||
+ private Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = Maps.newConcurrentMap();
|
+ private Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = Maps.newConcurrentMap();
|
||||||
+ public Map<SensorType<? extends Sensor<? super E>>, Sensor<? super E>> sensors = Maps.newLinkedHashMap();
|
+ public Map<SensorType<? extends Sensor<? super E>>, Sensor<? super E>> sensors = Maps.newLinkedHashMap();
|
||||||
private final Map<Integer, Map<Activity, Set<BehaviorControl<? super E>>>> availableBehaviorsByPriority = Maps.newTreeMap();
|
private final Map<Integer, Map<Activity, Set<BehaviorControl<? super E>>>> availableBehaviorsByPriority = Maps.newTreeMap();
|
||||||
private Schedule schedule = Schedule.EMPTY;
|
private Schedule schedule = Schedule.EMPTY;
|
||||||
- private final Map<Activity, Set<Pair<MemoryModuleType<?>, MemoryStatus>>> activityRequirements = Maps.newHashMap();
|
- private final Map<Activity, Set<Pair<MemoryModuleType<?>, MemoryStatus>>> activityRequirements = Maps.newHashMap();
|
||||||
+ private Map<Activity, Set<Pair<MemoryModuleType<?>, MemoryStatus>>> activityRequirements = Maps.newHashMap();
|
+ private Map<Activity, Set<Pair<MemoryModuleType<?>, MemoryStatus>>> activityRequirements = Maps.newHashMap();
|
||||||
+ // DivineMC end - Optimize entity brain
|
+ // DivineMC end - Optimize entities
|
||||||
private final Map<Activity, Set<MemoryModuleType<?>>> activityMemoriesToEraseWhenStopped = Maps.newHashMap();
|
private final Map<Activity, Set<MemoryModuleType<?>>> activityMemoriesToEraseWhenStopped = Maps.newHashMap();
|
||||||
private Set<Activity> coreActivities = Sets.newHashSet();
|
private Set<Activity> coreActivities = Sets.newHashSet();
|
||||||
private final Set<Activity> activeActivities = Sets.newHashSet();
|
private final Set<Activity> activeActivities = Sets.newHashSet();
|
||||||
private Activity defaultActivity = Activity.IDLE;
|
private Activity defaultActivity = Activity.IDLE;
|
||||||
private long lastScheduleUpdate = -9999L;
|
private long lastScheduleUpdate = -9999L;
|
||||||
+ // DivineMC start - Optimize entity brain
|
+ // DivineMC start - Optimize entities
|
||||||
+ private java.util.ArrayList<net.minecraft.world.entity.ai.behavior.BehaviorControl<? super E>> possibleTasks;
|
+ private java.util.ArrayList<net.minecraft.world.entity.ai.behavior.BehaviorControl<? super E>> possibleTasks;
|
||||||
+ private org.bxteam.divinemc.util.collections.MaskedList<net.minecraft.world.entity.ai.behavior.BehaviorControl<? super E>> runningTasks;
|
+ private org.bxteam.divinemc.util.collections.MaskedList<net.minecraft.world.entity.ai.behavior.BehaviorControl<? super E>> runningTasks;
|
||||||
+
|
+
|
||||||
@@ -104,7 +296,7 @@ index 99ced3cb7d3d4c7a80d890689d7585fa9acd17f6..9277b5da6065a5500e40727815083da2
|
|||||||
+ }
|
+ }
|
||||||
+ this.runningTasks = list;
|
+ this.runningTasks = list;
|
||||||
+ }
|
+ }
|
||||||
+ // DivineMC end - Optimize entity brain
|
+ // DivineMC end - Optimize entities
|
||||||
|
|
||||||
public static <E extends LivingEntity> Brain.Provider<E> provider(
|
public static <E extends LivingEntity> Brain.Provider<E> provider(
|
||||||
Collection<? extends MemoryModuleType<?>> memoryTypes, Collection<? extends SensorType<? extends Sensor<? super E>>> sensorTypes
|
Collection<? extends MemoryModuleType<?>> memoryTypes, Collection<? extends SensorType<? extends Sensor<? super E>>> sensorTypes
|
||||||
@@ -112,12 +304,12 @@ index 99ced3cb7d3d4c7a80d890689d7585fa9acd17f6..9277b5da6065a5500e40727815083da2
|
|||||||
for (Brain.MemoryValue<?> memoryValue : memoryValues) {
|
for (Brain.MemoryValue<?> memoryValue : memoryValues) {
|
||||||
memoryValue.setMemoryInternal(this);
|
memoryValue.setMemoryInternal(this);
|
||||||
}
|
}
|
||||||
+ // DivineMC start - Optimize entity brain
|
+ // DivineMC start - Optimize entities
|
||||||
+ this.onTasksChanged();
|
+ this.onTasksChanged();
|
||||||
+ this.memories = new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(this.memories);
|
+ this.memories = new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(this.memories);
|
||||||
+ this.sensors = new it.unimi.dsi.fastutil.objects.Reference2ReferenceLinkedOpenHashMap<>(this.sensors);
|
+ this.sensors = new it.unimi.dsi.fastutil.objects.Reference2ReferenceLinkedOpenHashMap<>(this.sensors);
|
||||||
+ this.activityRequirements = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.activityRequirements);
|
+ this.activityRequirements = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.activityRequirements);
|
||||||
+ // DivineMC end - Optimize entity brain
|
+ // DivineMC end - Optimize entities
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> DataResult<T> serializeStart(DynamicOps<T> ops) {
|
public <T> DataResult<T> serializeStart(DynamicOps<T> ops) {
|
||||||
@@ -125,7 +317,7 @@ index 99ced3cb7d3d4c7a80d890689d7585fa9acd17f6..9277b5da6065a5500e40727815083da2
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <U> void eraseMemory(MemoryModuleType<U> type) {
|
public <U> void eraseMemory(MemoryModuleType<U> type) {
|
||||||
+ if (!this.memories.containsKey(type)) return; // DivineMC - skip if memory does not contain key
|
+ if (!this.memories.containsKey(type)) return; // DivineMC - Optimize entities
|
||||||
this.setMemory(type, Optional.empty());
|
this.setMemory(type, Optional.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +325,7 @@ index 99ced3cb7d3d4c7a80d890689d7585fa9acd17f6..9277b5da6065a5500e40727815083da2
|
|||||||
this.setMemoryInternal(memoryType, memory.map(ExpirableValue::of));
|
this.setMemoryInternal(memoryType, memory.map(ExpirableValue::of));
|
||||||
}
|
}
|
||||||
|
|
||||||
+ // DivineMC start - Optimize entity brain
|
+ // DivineMC start - Optimize entities
|
||||||
<U> void setMemoryInternal(MemoryModuleType<U> memoryType, Optional<? extends ExpirableValue<?>> memory) {
|
<U> void setMemoryInternal(MemoryModuleType<U> memoryType, Optional<? extends ExpirableValue<?>> memory) {
|
||||||
+ if (memory.isPresent() && this.isEmptyCollection(memory.get().getValue())) {
|
+ if (memory.isPresent() && this.isEmptyCollection(memory.get().getValue())) {
|
||||||
+ this.eraseMemory(memoryType);
|
+ this.eraseMemory(memoryType);
|
||||||
@@ -163,7 +355,7 @@ index 99ced3cb7d3d4c7a80d890689d7585fa9acd17f6..9277b5da6065a5500e40727815083da2
|
|||||||
+ }
|
+ }
|
||||||
+ return oldValue;
|
+ return oldValue;
|
||||||
+ }
|
+ }
|
||||||
+ // DivineMC end - Optimize entity brain
|
+ // DivineMC end - Optimize entities
|
||||||
+
|
+
|
||||||
public <U> Optional<U> getMemory(MemoryModuleType<U> type) {
|
public <U> Optional<U> getMemory(MemoryModuleType<U> type) {
|
||||||
Optional<? extends ExpirableValue<?>> optional = this.memories.get(type);
|
Optional<? extends ExpirableValue<?>> optional = this.memories.get(type);
|
||||||
@@ -185,7 +377,7 @@ index 99ced3cb7d3d4c7a80d890689d7585fa9acd17f6..9277b5da6065a5500e40727815083da2
|
|||||||
- }
|
- }
|
||||||
-
|
-
|
||||||
- return list;
|
- return list;
|
||||||
+ return this.getCurrentlyRunningTasks(); // DivineMC - Optimize entity brain
|
+ return this.getCurrentlyRunningTasks(); // DivineMC - Optimize entities
|
||||||
}
|
}
|
||||||
|
|
||||||
public void useDefaultActivity() {
|
public void useDefaultActivity() {
|
||||||
@@ -193,7 +385,7 @@ index 99ced3cb7d3d4c7a80d890689d7585fa9acd17f6..9277b5da6065a5500e40727815083da2
|
|||||||
this.activeActivities.clear();
|
this.activeActivities.clear();
|
||||||
this.activeActivities.addAll(this.coreActivities);
|
this.activeActivities.addAll(this.coreActivities);
|
||||||
this.activeActivities.add(activity);
|
this.activeActivities.add(activity);
|
||||||
+ this.onPossibleActivitiesChanged(); // DivineMC - Optimize entity brain
|
+ this.onPossibleActivitiesChanged(); // DivineMC - Optimize entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,13 +393,13 @@ index 99ced3cb7d3d4c7a80d890689d7585fa9acd17f6..9277b5da6065a5500e40727815083da2
|
|||||||
.computeIfAbsent(activity, activity1 -> Sets.newLinkedHashSet())
|
.computeIfAbsent(activity, activity1 -> Sets.newLinkedHashSet())
|
||||||
.add((BehaviorControl<? super E>)pair.getSecond());
|
.add((BehaviorControl<? super E>)pair.getSecond());
|
||||||
}
|
}
|
||||||
+ this.onTasksChanged(); // DivineMC - Optimize entity brain
|
+ this.onTasksChanged(); // DivineMC - Optimize entities
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public void removeAllBehaviors() {
|
public void removeAllBehaviors() {
|
||||||
this.availableBehaviorsByPriority.clear();
|
this.availableBehaviorsByPriority.clear();
|
||||||
+ this.onTasksChanged(); // DivineMC - Optimize entity brain
|
+ this.onTasksChanged(); // DivineMC - Optimize entities
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isActive(Activity activity) {
|
public boolean isActive(Activity activity) {
|
||||||
@@ -215,7 +407,7 @@ index 99ced3cb7d3d4c7a80d890689d7585fa9acd17f6..9277b5da6065a5500e40727815083da2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ brain.memoryModCount = this.memoryModCount + 1; // DivineMC - Optimize entity brain
|
+ brain.memoryModCount = this.memoryModCount + 1; // DivineMC - Optimize entities
|
||||||
return brain;
|
return brain;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,15 +415,15 @@ index 99ced3cb7d3d4c7a80d890689d7585fa9acd17f6..9277b5da6065a5500e40727815083da2
|
|||||||
|
|
||||||
for (BehaviorControl<? super E> behaviorControl : this.getRunningBehaviors()) {
|
for (BehaviorControl<? super E> behaviorControl : this.getRunningBehaviors()) {
|
||||||
behaviorControl.doStop(level, owner, gameTime);
|
behaviorControl.doStop(level, owner, gameTime);
|
||||||
+ // DivineMC start - Optimize entity brain
|
+ // DivineMC start - Optimize entities
|
||||||
+ if (this.runningTasks != null) {
|
+ if (this.runningTasks != null) {
|
||||||
+ this.runningTasks.setVisible(behaviorControl, false);
|
+ this.runningTasks.setVisible(behaviorControl, false);
|
||||||
+ }
|
+ }
|
||||||
+ // DivineMC end - Optimize entity brain
|
+ // DivineMC end - Optimize entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ // DivineMC start - Optimize entity brain
|
+ // DivineMC start - Optimize entities
|
||||||
private void startEachNonRunningBehavior(ServerLevel level, E entity) {
|
private void startEachNonRunningBehavior(ServerLevel level, E entity) {
|
||||||
- long gameTime = level.getGameTime();
|
- long gameTime = level.getGameTime();
|
||||||
-
|
-
|
||||||
@@ -254,33 +446,33 @@ index 99ced3cb7d3d4c7a80d890689d7585fa9acd17f6..9277b5da6065a5500e40727815083da2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+ // DivineMC end - Optimize entity brain
|
+ // DivineMC end - Optimize entities
|
||||||
|
|
||||||
private void tickEachRunningBehavior(ServerLevel level, E entity) {
|
private void tickEachRunningBehavior(ServerLevel level, E entity) {
|
||||||
long gameTime = level.getGameTime();
|
long gameTime = level.getGameTime();
|
||||||
|
|
||||||
for (BehaviorControl<? super E> behaviorControl : this.getRunningBehaviors()) {
|
for (BehaviorControl<? super E> behaviorControl : this.getRunningBehaviors()) {
|
||||||
behaviorControl.tickOrStop(level, entity, gameTime);
|
behaviorControl.tickOrStop(level, entity, gameTime);
|
||||||
+ // DivineMC start - Optimize entity brain
|
+ // DivineMC start - Optimize entities
|
||||||
+ if (this.runningTasks != null && behaviorControl.getStatus() != Behavior.Status.RUNNING) {
|
+ if (this.runningTasks != null && behaviorControl.getStatus() != Behavior.Status.RUNNING) {
|
||||||
+ this.runningTasks.setVisible(behaviorControl, false);
|
+ this.runningTasks.setVisible(behaviorControl, false);
|
||||||
+ }
|
+ }
|
||||||
+ // DivineMC end - Optimize entity brain
|
+ // DivineMC end - Optimize entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/entity/ai/behavior/Behavior.java b/net/minecraft/world/entity/ai/behavior/Behavior.java
|
diff --git a/net/minecraft/world/entity/ai/behavior/Behavior.java b/net/minecraft/world/entity/ai/behavior/Behavior.java
|
||||||
index 5b0cadd2544fb2a627822e645ff32fec2e9cfda9..f367012ebcc4d06ac868bbc1733bee39ad2d67b1 100644
|
index 5b0cadd2544fb2a627822e645ff32fec2e9cfda9..02508662c722a515cfd78f872c8ba8bbffd8b6fb 100644
|
||||||
--- a/net/minecraft/world/entity/ai/behavior/Behavior.java
|
--- a/net/minecraft/world/entity/ai/behavior/Behavior.java
|
||||||
+++ b/net/minecraft/world/entity/ai/behavior/Behavior.java
|
+++ b/net/minecraft/world/entity/ai/behavior/Behavior.java
|
||||||
@@ -14,6 +14,10 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
|
@@ -14,6 +14,10 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
|
||||||
private long endTimestamp;
|
private long endTimestamp;
|
||||||
private final int minDuration;
|
private final int minDuration;
|
||||||
private final int maxDuration;
|
private final int maxDuration;
|
||||||
+ // DivineMC start - Optimize entity brain
|
+ // DivineMC start - Optimize entities
|
||||||
+ private long cachedMemoryModCount = -1;
|
+ private long cachedMemoryModCount = -1;
|
||||||
+ private boolean cachedHasRequiredMemoryState;
|
+ private boolean cachedHasRequiredMemoryState;
|
||||||
+ // DivineMC end - Optimize entity brain
|
+ // DivineMC end - Optimize entities
|
||||||
private final String configKey; // Paper - configurable behavior tick rate and timings
|
private final String configKey; // Paper - configurable behavior tick rate and timings
|
||||||
|
|
||||||
public Behavior(Map<MemoryModuleType<?>, MemoryStatus> entryCondition) {
|
public Behavior(Map<MemoryModuleType<?>, MemoryStatus> entryCondition) {
|
||||||
@@ -289,7 +481,7 @@ index 5b0cadd2544fb2a627822e645ff32fec2e9cfda9..f367012ebcc4d06ac868bbc1733bee39
|
|||||||
this.minDuration = minDuration;
|
this.minDuration = minDuration;
|
||||||
this.maxDuration = maxDuration;
|
this.maxDuration = maxDuration;
|
||||||
- this.entryCondition = entryCondition;
|
- this.entryCondition = entryCondition;
|
||||||
+ this.entryCondition = new it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap<>(entryCondition); // DivineMC - Optimize entity brain - Use fastutil
|
+ this.entryCondition = new it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap<>(entryCondition); // DivineMC - Optimize entities - Use fastutil
|
||||||
// Paper start - configurable behavior tick rate and timings
|
// Paper start - configurable behavior tick rate and timings
|
||||||
String key = io.papermc.paper.util.MappingEnvironment.reobf() ? io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName()) : this.getClass().getName();
|
String key = io.papermc.paper.util.MappingEnvironment.reobf() ? io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName()) : this.getClass().getName();
|
||||||
int lastSeparator = key.lastIndexOf('.');
|
int lastSeparator = key.lastIndexOf('.');
|
||||||
@@ -303,7 +495,7 @@ index 5b0cadd2544fb2a627822e645ff32fec2e9cfda9..f367012ebcc4d06ac868bbc1733bee39
|
|||||||
- MemoryStatus memoryStatus = entry.getValue();
|
- MemoryStatus memoryStatus = entry.getValue();
|
||||||
- if (!owner.getBrain().checkMemory(memoryModuleType, memoryStatus)) {
|
- if (!owner.getBrain().checkMemory(memoryModuleType, memoryStatus)) {
|
||||||
- return false;
|
- return false;
|
||||||
+ // DivineMC start - Optimize entity brain
|
+ // DivineMC start - Optimize entities
|
||||||
+ public boolean hasRequiredMemories(E entity) {
|
+ public boolean hasRequiredMemories(E entity) {
|
||||||
+ net.minecraft.world.entity.ai.Brain<?> brain = entity.getBrain();
|
+ net.minecraft.world.entity.ai.Brain<?> brain = entity.getBrain();
|
||||||
+ long modCount = brain.getMemoryModCount();
|
+ long modCount = brain.getMemoryModCount();
|
||||||
@@ -323,24 +515,24 @@ index 5b0cadd2544fb2a627822e645ff32fec2e9cfda9..f367012ebcc4d06ac868bbc1733bee39
|
|||||||
- return true;
|
- return true;
|
||||||
+ return this.cachedHasRequiredMemoryState = true;
|
+ return this.cachedHasRequiredMemoryState = true;
|
||||||
}
|
}
|
||||||
+ // DivineMC end - Optimize entity brain
|
+ // DivineMC end - Optimize entities
|
||||||
|
|
||||||
public static enum Status {
|
public static enum Status {
|
||||||
STOPPED,
|
STOPPED,
|
||||||
diff --git a/net/minecraft/world/entity/ai/behavior/LongJumpToRandomPos.java b/net/minecraft/world/entity/ai/behavior/LongJumpToRandomPos.java
|
diff --git a/net/minecraft/world/entity/ai/behavior/LongJumpToRandomPos.java b/net/minecraft/world/entity/ai/behavior/LongJumpToRandomPos.java
|
||||||
index 977afa268838304abdb34be253ca36ac1c22e99f..ff04ea295b70583137deb8babe5e75ebc755f697 100644
|
index 977afa268838304abdb34be253ca36ac1c22e99f..9fdb2ce7b72d0a10c2148027990a0048ca93f976 100644
|
||||||
--- a/net/minecraft/world/entity/ai/behavior/LongJumpToRandomPos.java
|
--- a/net/minecraft/world/entity/ai/behavior/LongJumpToRandomPos.java
|
||||||
+++ b/net/minecraft/world/entity/ai/behavior/LongJumpToRandomPos.java
|
+++ b/net/minecraft/world/entity/ai/behavior/LongJumpToRandomPos.java
|
||||||
@@ -119,6 +119,12 @@ public class LongJumpToRandomPos<E extends Mob> extends Behavior<E> {
|
@@ -119,6 +119,12 @@ public class LongJumpToRandomPos<E extends Mob> extends Behavior<E> {
|
||||||
int x = blockPos.getX();
|
int x = blockPos.getX();
|
||||||
int y = blockPos.getY();
|
int y = blockPos.getY();
|
||||||
int z = blockPos.getZ();
|
int z = blockPos.getZ();
|
||||||
+ // DivineMC start - Optimize entity brain
|
+ // DivineMC start - Optimize entities
|
||||||
+ if (this.maxLongJumpWidth < 128 && this.maxLongJumpHeight < 128) {
|
+ if (this.maxLongJumpWidth < 128 && this.maxLongJumpHeight < 128) {
|
||||||
+ this.jumpCandidates = org.bxteam.divinemc.util.collections.LongJumpChoiceList.forCenter(blockPos, (byte) this.maxLongJumpWidth, (byte) this.maxLongJumpHeight);
|
+ this.jumpCandidates = org.bxteam.divinemc.util.collections.LongJumpChoiceList.forCenter(blockPos, (byte) this.maxLongJumpWidth, (byte) this.maxLongJumpHeight);
|
||||||
+ return;
|
+ return;
|
||||||
+ }
|
+ }
|
||||||
+ // DivineMC end - Optimize entity brain
|
+ // DivineMC end - Optimize entities
|
||||||
this.jumpCandidates = BlockPos.betweenClosedStream(
|
this.jumpCandidates = BlockPos.betweenClosedStream(
|
||||||
x - this.maxLongJumpWidth,
|
x - this.maxLongJumpWidth,
|
||||||
y - this.maxLongJumpHeight,
|
y - this.maxLongJumpHeight,
|
||||||
@@ -348,7 +540,7 @@ index 977afa268838304abdb34be253ca36ac1c22e99f..ff04ea295b70583137deb8babe5e75eb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ // DivineMC start - Optimize entity brain
|
+ // DivineMC start - Optimize entities
|
||||||
protected Optional<LongJumpToRandomPos.PossibleJump> getJumpCandidate(ServerLevel level) {
|
protected Optional<LongJumpToRandomPos.PossibleJump> getJumpCandidate(ServerLevel level) {
|
||||||
- Optional<LongJumpToRandomPos.PossibleJump> randomItem = WeightedRandom.getRandomItem(
|
- Optional<LongJumpToRandomPos.PossibleJump> randomItem = WeightedRandom.getRandomItem(
|
||||||
- level.random, this.jumpCandidates, LongJumpToRandomPos.PossibleJump::weight
|
- level.random, this.jumpCandidates, LongJumpToRandomPos.PossibleJump::weight
|
||||||
@@ -375,6 +567,23 @@ index 977afa268838304abdb34be253ca36ac1c22e99f..ff04ea295b70583137deb8babe5e75eb
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAcceptableLandingPosition(ServerLevel level, E entity, BlockPos pos) {
|
private boolean isAcceptableLandingPosition(ServerLevel level, E entity, BlockPos pos) {
|
||||||
|
diff --git a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
|
||||||
|
index b0c5e41fefc7c9adf1a61bd5b52861736657d37e..dfc62772d5617f0dce72b45a1bebf1b2f051efd5 100644
|
||||||
|
--- a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
|
||||||
|
+++ b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
|
||||||
|
@@ -17,10 +17,10 @@ public class NearestLivingEntitySensor<T extends LivingEntity> extends Sensor<T>
|
||||||
|
protected void doTick(ServerLevel level, T entity) {
|
||||||
|
double attributeValue = entity.getAttributeValue(Attributes.FOLLOW_RANGE);
|
||||||
|
AABB aabb = entity.getBoundingBox().inflate(attributeValue, attributeValue, attributeValue);
|
||||||
|
- List<LivingEntity> entitiesOfClass = level.getEntitiesOfClass(
|
||||||
|
+ it.unimi.dsi.fastutil.objects.ObjectArrayList<LivingEntity> entitiesOfClass = (it.unimi.dsi.fastutil.objects.ObjectArrayList<LivingEntity>) level.getEntitiesOfClass( // DivineMC - Optimize collections
|
||||||
|
LivingEntity.class, aabb, matchableEntity -> matchableEntity != entity && matchableEntity.isAlive()
|
||||||
|
);
|
||||||
|
- entitiesOfClass.sort(Comparator.comparingDouble(entity::distanceToSqr));
|
||||||
|
+ entitiesOfClass.unstableSort(Comparator.comparingDouble(entity::distanceToSqr)); // DivineMC - Optimize collections
|
||||||
|
Brain<?> brain = entity.getBrain();
|
||||||
|
brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, entitiesOfClass);
|
||||||
|
brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(level, entity, entitiesOfClass));
|
||||||
diff --git a/net/minecraft/world/entity/ai/sensing/VillagerBabiesSensor.java b/net/minecraft/world/entity/ai/sensing/VillagerBabiesSensor.java
|
diff --git a/net/minecraft/world/entity/ai/sensing/VillagerBabiesSensor.java b/net/minecraft/world/entity/ai/sensing/VillagerBabiesSensor.java
|
||||||
index 24d1928445b5571e040a2b12d5c82e77a880d9bd..dac0a23aebf2dea1972c07d5c82079da7c9837ac 100644
|
index 24d1928445b5571e040a2b12d5c82e77a880d9bd..dac0a23aebf2dea1972c07d5c82079da7c9837ac 100644
|
||||||
--- a/net/minecraft/world/entity/ai/sensing/VillagerBabiesSensor.java
|
--- a/net/minecraft/world/entity/ai/sensing/VillagerBabiesSensor.java
|
||||||
@@ -404,38 +613,38 @@ index 24d1928445b5571e040a2b12d5c82e77a880d9bd..dac0a23aebf2dea1972c07d5c82079da
|
|||||||
private boolean isVillagerBaby(LivingEntity livingEntity) {
|
private boolean isVillagerBaby(LivingEntity livingEntity) {
|
||||||
return livingEntity.getType() == EntityType.VILLAGER && livingEntity.isBaby();
|
return livingEntity.getType() == EntityType.VILLAGER && livingEntity.isBaby();
|
||||||
diff --git a/net/minecraft/world/entity/animal/goat/Goat.java b/net/minecraft/world/entity/animal/goat/Goat.java
|
diff --git a/net/minecraft/world/entity/animal/goat/Goat.java b/net/minecraft/world/entity/animal/goat/Goat.java
|
||||||
index 70b32e0d06f9b8b7999df5fdfd773c09394e23fb..997cff138d5c99b1be9224cb3c96bdfeeb79915a 100644
|
index 70b32e0d06f9b8b7999df5fdfd773c09394e23fb..188c233721d7a98c8a437dd5bd155b1f3de9134e 100644
|
||||||
--- a/net/minecraft/world/entity/animal/goat/Goat.java
|
--- a/net/minecraft/world/entity/animal/goat/Goat.java
|
||||||
+++ b/net/minecraft/world/entity/animal/goat/Goat.java
|
+++ b/net/minecraft/world/entity/animal/goat/Goat.java
|
||||||
@@ -100,6 +100,13 @@ public class Goat extends Animal {
|
@@ -100,6 +100,13 @@ public class Goat extends Animal {
|
||||||
this.getNavigation().setCanFloat(true);
|
this.getNavigation().setCanFloat(true);
|
||||||
this.setPathfindingMalus(PathType.POWDER_SNOW, -1.0F);
|
this.setPathfindingMalus(PathType.POWDER_SNOW, -1.0F);
|
||||||
this.setPathfindingMalus(PathType.DANGER_POWDER_SNOW, -1.0F);
|
this.setPathfindingMalus(PathType.DANGER_POWDER_SNOW, -1.0F);
|
||||||
+ // DivineMC start - Optimize entity brain
|
+ // DivineMC start - Optimize entities
|
||||||
+ if (!this.getBrain().hasMemoryValue(MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM)) {
|
+ if (!this.getBrain().hasMemoryValue(MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM)) {
|
||||||
+ org.bxteam.divinemc.util.entity.SensorHelper.disableSensor(this, SensorType.NEAREST_ITEMS);
|
+ org.bxteam.divinemc.util.entity.SensorHelper.disableSensor(this, SensorType.NEAREST_ITEMS);
|
||||||
+ } else if (net.minecraft.SharedConstants.IS_RUNNING_IN_IDE) {
|
+ } else if (net.minecraft.SharedConstants.IS_RUNNING_IN_IDE) {
|
||||||
+ throw new IllegalStateException("Goat Entity has a nearest visible wanted item memory module! This patch(Optimize-Brain, Goat.java changes) should probably be removed permanently!");
|
+ throw new IllegalStateException("Goat Entity has a nearest visible wanted item memory module! This patch(Optimize-Brain, Goat.java changes) should probably be removed permanently!");
|
||||||
+ }
|
+ }
|
||||||
+ // DivineMC end - Optimize entity brain
|
+ // DivineMC end - Optimize entities
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack createHorn() {
|
public ItemStack createHorn() {
|
||||||
diff --git a/net/minecraft/world/entity/schedule/Activity.java b/net/minecraft/world/entity/schedule/Activity.java
|
diff --git a/net/minecraft/world/entity/schedule/Activity.java b/net/minecraft/world/entity/schedule/Activity.java
|
||||||
index 5a143bb6fabba3dc4e2272afb0be636d5722ea22..f17cc8135121f1a97f13bf83a0205e7fcb08b431 100644
|
index 5a143bb6fabba3dc4e2272afb0be636d5722ea22..133a51ed45500aba7b0bc4a7acb19731a524d8c1 100644
|
||||||
--- a/net/minecraft/world/entity/schedule/Activity.java
|
--- a/net/minecraft/world/entity/schedule/Activity.java
|
||||||
+++ b/net/minecraft/world/entity/schedule/Activity.java
|
+++ b/net/minecraft/world/entity/schedule/Activity.java
|
||||||
@@ -32,10 +32,12 @@ public class Activity {
|
@@ -32,10 +32,12 @@ public class Activity {
|
||||||
public static final Activity DIG = register("dig");
|
public static final Activity DIG = register("dig");
|
||||||
private final String name;
|
private final String name;
|
||||||
private final int hashCode;
|
private final int hashCode;
|
||||||
+ public final int id; // DivineMC - Cache registry ID
|
+ public final int id; // DivineMC - Optimize entities - cache registry ID
|
||||||
|
|
||||||
- private Activity(String name) {
|
- private Activity(String name) {
|
||||||
+ private Activity(String name, int id) {
|
+ private Activity(String name, int id) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.hashCode = name.hashCode();
|
this.hashCode = name.hashCode();
|
||||||
+ this.id = id; // DivineMC - Cache registry ID
|
+ this.id = id; // DivineMC - Optimize entities - cache registry ID
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@@ -444,7 +653,7 @@ index 5a143bb6fabba3dc4e2272afb0be636d5722ea22..f17cc8135121f1a97f13bf83a0205e7f
|
|||||||
|
|
||||||
private static Activity register(String key) {
|
private static Activity register(String key) {
|
||||||
- return Registry.register(BuiltInRegistries.ACTIVITY, key, new Activity(key));
|
- return Registry.register(BuiltInRegistries.ACTIVITY, key, new Activity(key));
|
||||||
+ return Registry.register(BuiltInRegistries.ACTIVITY, key, new Activity(key, BuiltInRegistries.ACTIVITY.size())); // DivineMC - Cache registry ID
|
+ return Registry.register(BuiltInRegistries.ACTIVITY, key, new Activity(key, BuiltInRegistries.ACTIVITY.size())); // DivineMC - Optimize entities - cache registry ID
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -640,10 +640,10 @@ index f9e7532f86122a379692561a639a209a126e8bba..839f6b7696ef85314da185bedba7cfc5
|
|||||||
if (isLocatorBarEnabledFor(player)) {
|
if (isLocatorBarEnabledFor(player)) {
|
||||||
if (!connection.isBroken()) {
|
if (!connection.isBroken()) {
|
||||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||||
index 461abfac4749ca06b613cfee9e1ad9e6961299df..137b786bf15bbbe52f22bd9e25c1ef3c0d04e642 100644
|
index 6963be899ac218bd091e73b72c9ccef82e33de36..85da5aec677d84aea005449d97c1ee3ca616e2e4 100644
|
||||||
--- a/net/minecraft/world/entity/Entity.java
|
--- a/net/minecraft/world/entity/Entity.java
|
||||||
+++ b/net/minecraft/world/entity/Entity.java
|
+++ b/net/minecraft/world/entity/Entity.java
|
||||||
@@ -3461,14 +3461,34 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -3480,14 +3480,34 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
if (this.portalProcess != null) {
|
if (this.portalProcess != null) {
|
||||||
if (this.portalProcess.processPortalTeleportation(serverLevel, this, this.canUsePortal(false))) {
|
if (this.portalProcess.processPortalTeleportation(serverLevel, this, this.canUsePortal(false))) {
|
||||||
this.setPortalCooldown();
|
this.setPortalCooldown();
|
||||||
@@ -684,7 +684,7 @@ index 461abfac4749ca06b613cfee9e1ad9e6961299df..137b786bf15bbbe52f22bd9e25c1ef3c
|
|||||||
} else if (this.portalProcess.hasExpired()) {
|
} else if (this.portalProcess.hasExpired()) {
|
||||||
this.portalProcess = null;
|
this.portalProcess = null;
|
||||||
}
|
}
|
||||||
@@ -4045,6 +4065,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -4064,6 +4084,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
private Entity teleportCrossDimension(ServerLevel oldLevel, ServerLevel newLevel, TeleportTransition teleportTransition) {
|
private Entity teleportCrossDimension(ServerLevel oldLevel, ServerLevel newLevel, TeleportTransition teleportTransition) {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ index 7ca147cf9da67c399806056e5092841f7ca32321..a6bf257ca93e4b3819b65b4ef4ba71d9
|
|||||||
double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
|
double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
|
||||||
if (rangeY != -1) {
|
if (rangeY != -1) {
|
||||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||||
index 0915a08bc8d2dd38ade01e31c34abd69e1abd365..b720230c4bef699fa1b60d949c47aa4c193a24db 100644
|
index 85da5aec677d84aea005449d97c1ee3ca616e2e4..4c9e0eaedad3f4a372b48580cbe9b03fe2f8c037 100644
|
||||||
--- a/net/minecraft/world/entity/Entity.java
|
--- a/net/minecraft/world/entity/Entity.java
|
||||||
+++ b/net/minecraft/world/entity/Entity.java
|
+++ b/net/minecraft/world/entity/Entity.java
|
||||||
@@ -145,7 +145,7 @@ import net.minecraft.world.waypoints.WaypointTransmitter;
|
@@ -145,7 +145,7 @@ import net.minecraft.world.waypoints.WaypointTransmitter;
|
||||||
@@ -35,7 +35,7 @@ index 0915a08bc8d2dd38ade01e31c34abd69e1abd365..b720230c4bef699fa1b60d949c47aa4c
|
|||||||
public static javax.script.ScriptEngine scriptEngine = new javax.script.ScriptEngineManager().getEngineByName("rhino"); // Purpur - Configurable entity base attributes
|
public static javax.script.ScriptEngine scriptEngine = new javax.script.ScriptEngineManager().getEngineByName("rhino"); // Purpur - Configurable entity base attributes
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
private static final int CURRENT_LEVEL = 2;
|
private static final int CURRENT_LEVEL = 2;
|
||||||
@@ -5476,4 +5476,47 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -5495,4 +5495,47 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Purpur end - Ridables
|
// Purpur end - Ridables
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ index 0ad18866c323308ad9b87322932e03a283f740b1..386fdc23b35675a7db66d16bf2a8a6dd
|
|||||||
|
|
||||||
private void tickPassenger(Entity ridingEntity, Entity passengerEntity, final boolean isActive) { // Paper - EAR 2
|
private void tickPassenger(Entity ridingEntity, Entity passengerEntity, final boolean isActive) { // Paper - EAR 2
|
||||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||||
index b720230c4bef699fa1b60d949c47aa4c193a24db..c671370a0addb31bc8ca7d7fa642d3b53b5c00ee 100644
|
index 4c9e0eaedad3f4a372b48580cbe9b03fe2f8c037..d947bff42cbf7aaac0b7f62bc78c239a5f6af381 100644
|
||||||
--- a/net/minecraft/world/entity/Entity.java
|
--- a/net/minecraft/world/entity/Entity.java
|
||||||
+++ b/net/minecraft/world/entity/Entity.java
|
+++ b/net/minecraft/world/entity/Entity.java
|
||||||
@@ -1111,29 +1111,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -1111,29 +1111,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
@@ -152,7 +152,7 @@ index b720230c4bef699fa1b60d949c47aa4c193a24db..c671370a0addb31bc8ca7d7fa642d3b5
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void applyMovementEmissionAndPlaySound(Entity.MovementEmission movementEmission, Vec3 movement, BlockPos pos, BlockState state) {
|
private void applyMovementEmissionAndPlaySound(Entity.MovementEmission movementEmission, Vec3 movement, BlockPos pos, BlockState state) {
|
||||||
@@ -4950,9 +4924,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -4969,9 +4943,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDeltaMovement(Vec3 deltaMovement) {
|
public void setDeltaMovement(Vec3 deltaMovement) {
|
||||||
@@ -162,7 +162,7 @@ index b720230c4bef699fa1b60d949c47aa4c193a24db..c671370a0addb31bc8ca7d7fa642d3b5
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addDeltaMovement(Vec3 addend) {
|
public void addDeltaMovement(Vec3 addend) {
|
||||||
@@ -5050,9 +5022,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -5069,9 +5041,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
}
|
}
|
||||||
// Paper end - Block invalid positions and bounding box
|
// Paper end - Block invalid positions and bounding box
|
||||||
if (this.position.x != x || this.position.y != y || this.position.z != z) {
|
if (this.position.x != x || this.position.y != y || this.position.z != z) {
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ index 6d1fe8028739145b11fce98ad62b2f8044299548..9f086ded18d1fc8850877c6be113d880
|
|||||||
// note: vanilla does not subtract 0.5 but the result is (luckily!) the same
|
// note: vanilla does not subtract 0.5 but the result is (luckily!) the same
|
||||||
public static final int NARROW_SPAWN_TRACK_RANGE = (int)Math.floor(((double)PLAYER_SPAWN_TRACK_RANGE / Math.sqrt(2.0)) - 0.5);
|
public static final int NARROW_SPAWN_TRACK_RANGE = (int)Math.floor(((double)PLAYER_SPAWN_TRACK_RANGE / Math.sqrt(2.0)) - 0.5);
|
||||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||||
index 038d75aa39a158b65887c81f2687cb3c8140a6e2..3ca2f56cb31d41e88eb2a3e59c3749fbdef7c85e 100644
|
index a6bf257ca93e4b3819b65b4ef4ba71d9e2b40933..de7800b46f7e8c68f24de8476032f2179edc4797 100644
|
||||||
--- a/net/minecraft/server/level/ChunkMap.java
|
--- a/net/minecraft/server/level/ChunkMap.java
|
||||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||||
@@ -824,10 +824,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
@@ -822,10 +822,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
final ServerPlayer[] raw = players.getRawDataUnchecked();
|
final ServerPlayer[] raw = players.getRawDataUnchecked();
|
||||||
final int len = players.size();
|
final int len = players.size();
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ index 038d75aa39a158b65887c81f2687cb3c8140a6e2..3ca2f56cb31d41e88eb2a3e59c3749fb
|
|||||||
if (ret == null) {
|
if (ret == null) {
|
||||||
ret = new ArrayList<>(len - i);
|
ret = new ArrayList<>(len - i);
|
||||||
ret.add(player);
|
ret.add(player);
|
||||||
@@ -1222,6 +1222,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
@@ -1220,6 +1220,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
|
|
||||||
for (int i = 0; i < playersLength; ++i) { // DivineMC - Multithreaded tracker
|
for (int i = 0; i < playersLength; ++i) { // DivineMC - Multithreaded tracker
|
||||||
final ServerPlayer player = playersRaw[i];
|
final ServerPlayer player = playersRaw[i];
|
||||||
@@ -37,7 +37,7 @@ index 7e31c5c8659d24948fd45a2d6ee7bdeca6027d27..95221434fd8eef388f0308b72af3f934
|
|||||||
|
|
||||||
protected NonNullList(List<E> list, @Nullable E defaultValue) {
|
protected NonNullList(List<E> list, @Nullable E defaultValue) {
|
||||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||||
index a6bf257ca93e4b3819b65b4ef4ba71d9e2b40933..038d75aa39a158b65887c81f2687cb3c8140a6e2 100644
|
index de7800b46f7e8c68f24de8476032f2179edc4797..3ca2f56cb31d41e88eb2a3e59c3749fbdef7c85e 100644
|
||||||
--- a/net/minecraft/server/level/ChunkMap.java
|
--- a/net/minecraft/server/level/ChunkMap.java
|
||||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||||
@@ -132,8 +132,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
@@ -132,8 +132,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
@@ -53,23 +53,19 @@ index a6bf257ca93e4b3819b65b4ef4ba71d9e2b40933..038d75aa39a158b65887c81f2687cb3c
|
|||||||
// Paper - rewrite chunk system
|
// Paper - rewrite chunk system
|
||||||
public int serverViewDistance;
|
public int serverViewDistance;
|
||||||
public final WorldGenContext worldGenContext; // Paper - public
|
public final WorldGenContext worldGenContext; // Paper - public
|
||||||
diff --git a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
|
diff --git a/net/minecraft/stats/StatType.java b/net/minecraft/stats/StatType.java
|
||||||
index b0c5e41fefc7c9adf1a61bd5b52861736657d37e..dfc62772d5617f0dce72b45a1bebf1b2f051efd5 100644
|
index e42b894f0bdecd9417c3d53bfc172cd0726340bc..0865554f79536dc324766346223413c670348600 100644
|
||||||
--- a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
|
--- a/net/minecraft/stats/StatType.java
|
||||||
+++ b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
|
+++ b/net/minecraft/stats/StatType.java
|
||||||
@@ -17,10 +17,10 @@ public class NearestLivingEntitySensor<T extends LivingEntity> extends Sensor<T>
|
@@ -11,7 +11,7 @@ import net.minecraft.network.codec.StreamCodec;
|
||||||
protected void doTick(ServerLevel level, T entity) {
|
|
||||||
double attributeValue = entity.getAttributeValue(Attributes.FOLLOW_RANGE);
|
public class StatType<T> implements Iterable<Stat<T>> {
|
||||||
AABB aabb = entity.getBoundingBox().inflate(attributeValue, attributeValue, attributeValue);
|
private final Registry<T> registry;
|
||||||
- List<LivingEntity> entitiesOfClass = level.getEntitiesOfClass(
|
- private final Map<T, Stat<T>> map = new IdentityHashMap<>();
|
||||||
+ it.unimi.dsi.fastutil.objects.ObjectArrayList<LivingEntity> entitiesOfClass = (it.unimi.dsi.fastutil.objects.ObjectArrayList<LivingEntity>) level.getEntitiesOfClass( // DivineMC - Optimize collections
|
+ private final Map<T, Stat<T>> map = new it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap<>(); // DivineMC - Optimize collections
|
||||||
LivingEntity.class, aabb, matchableEntity -> matchableEntity != entity && matchableEntity.isAlive()
|
private final Component displayName;
|
||||||
);
|
private final StreamCodec<RegistryFriendlyByteBuf, Stat<T>> streamCodec;
|
||||||
- entitiesOfClass.sort(Comparator.comparingDouble(entity::distanceToSqr));
|
|
||||||
+ entitiesOfClass.unstableSort(Comparator.comparingDouble(entity::distanceToSqr)); // DivineMC - Optimize collections
|
|
||||||
Brain<?> brain = entity.getBrain();
|
|
||||||
brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, entitiesOfClass);
|
|
||||||
brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(level, entity, entitiesOfClass));
|
|
||||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||||
index 66ba223dacefb3531c46b144c4499b2b2285eafe..0b7f9af0c4e43115878769043ebd06a09ccdf059 100644
|
index 66ba223dacefb3531c46b144c4499b2b2285eafe..0b7f9af0c4e43115878769043ebd06a09ccdf059 100644
|
||||||
--- a/net/minecraft/world/level/Level.java
|
--- a/net/minecraft/world/level/Level.java
|
||||||
@@ -92,16 +88,16 @@ index 66ba223dacefb3531c46b144c4499b2b2285eafe..0b7f9af0c4e43115878769043ebd06a0
|
|||||||
|
|
||||||
((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getHardCollidingEntities(entity, box, ret, predicate);
|
((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getHardCollidingEntities(entity, box, ret, predicate);
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
diff --git a/net/minecraft/world/level/chunk/ProtoChunk.java b/net/minecraft/world/level/chunk/ProtoChunk.java
|
||||||
index 24f13e2b0b694ff4dd01aeea876ef874f1828304..1135aa373a631cb90b6c0c75fd3590bcbefd4a4c 100644
|
index aa085d8a78a3fb40a214e4b152ab04d9a409f76f..5ed1a8b6ac025d03fdeb408a6eaa00320087f690 100644
|
||||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
--- a/net/minecraft/world/level/chunk/ProtoChunk.java
|
||||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
+++ b/net/minecraft/world/level/chunk/ProtoChunk.java
|
||||||
@@ -75,7 +75,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
@@ -46,7 +46,7 @@ public class ProtoChunk extends ChunkAccess {
|
||||||
return "<null>";
|
@Nullable
|
||||||
}
|
private volatile LevelLightEngine lightEngine;
|
||||||
};
|
private volatile ChunkStatus status = ChunkStatus.EMPTY;
|
||||||
- private final Map<BlockPos, LevelChunk.RebindableTickingBlockEntityWrapper> tickersInLevel = Maps.newHashMap();
|
- private final List<CompoundTag> entities = Lists.newArrayList();
|
||||||
+ private final Map<BlockPos, LevelChunk.RebindableTickingBlockEntityWrapper> tickersInLevel = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(); // DivineMC - Optimize collections
|
+ private final List<CompoundTag> entities = Collections.synchronizedList(Lists.newArrayList()); // DivineMC - Optimize collections
|
||||||
public boolean loaded;
|
@Nullable
|
||||||
public final ServerLevel level; // CraftBukkit - type
|
private CarvingMask carvingMask;
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||||
|
Date: Thu, 24 Jul 2025 14:07:47 +0300
|
||||||
|
Subject: [PATCH] Optimize level ticking
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
|
index 386fdc23b35675a7db66d16bf2a8a6dd5b44059a..4934ce03ac533d9c60674632cdac6621e62f6b44 100644
|
||||||
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
|
@@ -908,9 +908,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
|
// Paper start - optimise random ticking
|
||||||
|
private final ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom simpleRandom = new ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom(net.minecraft.world.level.levelgen.RandomSupport.generateUniqueSeed());
|
||||||
|
|
||||||
|
+ // DivineMC start - Optimize level ticking
|
||||||
|
private void optimiseRandomTick(final LevelChunk chunk, final int tickSpeed) {
|
||||||
|
final LevelChunkSection[] sections = chunk.getSections();
|
||||||
|
- final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection((ServerLevel)(Object)this);
|
||||||
|
+ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(this); // DivineMC - Optimize level ticking
|
||||||
|
final ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom simpleRandom = this.simpleRandom;
|
||||||
|
final boolean doubleTickFluids = !ca.spottedleaf.moonrise.common.PlatformHooks.get().configFixMC224294();
|
||||||
|
|
||||||
|
@@ -919,42 +920,38 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
|
final int offsetZ = cpos.z << 4;
|
||||||
|
|
||||||
|
for (int sectionIndex = 0, sectionsLen = sections.length; sectionIndex < sectionsLen; sectionIndex++) {
|
||||||
|
- final int offsetY = (sectionIndex + minSection) << 4;
|
||||||
|
final LevelChunkSection section = sections[sectionIndex];
|
||||||
|
+ if (!section.isRandomlyTickingBlocks()) continue;
|
||||||
|
+ final int offsetY = (sectionIndex + minSection) << 4;
|
||||||
|
final net.minecraft.world.level.chunk.PalettedContainer<net.minecraft.world.level.block.state.BlockState> states = section.states;
|
||||||
|
- if (!section.isRandomlyTickingBlocks()) {
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
|
||||||
|
- final ca.spottedleaf.moonrise.common.list.ShortList tickList = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$getTickingBlockList();
|
||||||
|
+ final ca.spottedleaf.moonrise.common.list.ShortList tickList = section.moonrise$getTickingBlockList();
|
||||||
|
|
||||||
|
for (int i = 0; i < tickSpeed; ++i) {
|
||||||
|
- final int tickingBlocks = tickList.size();
|
||||||
|
final int index = simpleRandom.nextInt() & ((16 * 16 * 16) - 1);
|
||||||
|
|
||||||
|
- if (index >= tickingBlocks) {
|
||||||
|
+ if (index >= tickList.size()) {
|
||||||
|
// most of the time we fall here
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- final int location = (int)tickList.getRaw(index) & 0xFFFF;
|
||||||
|
+ final int location = tickList.getRaw(index);
|
||||||
|
final BlockState state = states.get(location);
|
||||||
|
|
||||||
|
// do not use a mutable pos, as some random tick implementations store the input without calling immutable()!
|
||||||
|
- final BlockPos pos = new BlockPos((location & 15) | offsetX, ((location >>> (4 + 4)) & 15) | offsetY, ((location >>> 4) & 15) | offsetZ);
|
||||||
|
+ final BlockPos pos = new BlockPos((location & 15) | offsetX, (location >>> (4 + 4)) | offsetY, ((location >>> 4) & 15) | offsetZ);
|
||||||
|
|
||||||
|
- state.randomTick((ServerLevel)(Object)this, pos, simpleRandom);
|
||||||
|
+ state.randomTick(this, pos, simpleRandom);
|
||||||
|
if (doubleTickFluids) {
|
||||||
|
final FluidState fluidState = state.getFluidState();
|
||||||
|
if (fluidState.isRandomlyTicking()) {
|
||||||
|
- fluidState.randomTick((ServerLevel)(Object)this, pos, simpleRandom);
|
||||||
|
+ fluidState.randomTick(this, pos, simpleRandom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- return;
|
||||||
|
}
|
||||||
|
+ // DivineMC end - Optimize level ticking
|
||||||
|
// Paper end - optimise random ticking
|
||||||
|
|
||||||
|
public void tickChunk(LevelChunk chunk, int randomTickSpeed) {
|
||||||
|
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
|
index 24f13e2b0b694ff4dd01aeea876ef874f1828304..404ed7c6ebe2364b9404df6e29d07a0aed83ed08 100644
|
||||||
|
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
|
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
|
@@ -75,7 +75,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
||||||
|
return "<null>";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
- private final Map<BlockPos, LevelChunk.RebindableTickingBlockEntityWrapper> tickersInLevel = Maps.newHashMap();
|
||||||
|
+ private final Map<BlockPos, LevelChunk.RebindableTickingBlockEntityWrapper> tickersInLevel = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(); // DivineMC - Optimize level ticking
|
||||||
|
public boolean loaded;
|
||||||
|
public final ServerLevel level; // CraftBukkit - type
|
||||||
|
@Nullable
|
||||||
|
diff --git a/net/minecraft/world/ticks/LevelChunkTicks.java b/net/minecraft/world/ticks/LevelChunkTicks.java
|
||||||
|
index 66d0a6390febe929ef774b0a7813329015bc8cc2..c17549c4f8a877852c4b86453b1db7b17aab4665 100644
|
||||||
|
--- a/net/minecraft/world/ticks/LevelChunkTicks.java
|
||||||
|
+++ b/net/minecraft/world/ticks/LevelChunkTicks.java
|
||||||
|
@@ -14,10 +14,10 @@ import javax.annotation.Nullable;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
|
||||||
|
public class LevelChunkTicks<T> implements SerializableTickContainer<T>, TickContainerAccess<T>, ca.spottedleaf.moonrise.patches.chunk_system.ticks.ChunkSystemLevelChunkTicks { // Paper - rewrite chunk system
|
||||||
|
- private final Queue<ScheduledTick<T>> tickQueue = new PriorityQueue<>(ScheduledTick.DRAIN_ORDER);
|
||||||
|
+ private final Queue<ScheduledTick<T>> tickQueue = new java.util.concurrent.PriorityBlockingQueue<>(11, ScheduledTick.DRAIN_ORDER); // DivineMC - Optimize level ticking
|
||||||
|
@Nullable
|
||||||
|
private List<SavedTick<T>> pendingTicks;
|
||||||
|
- private final Set<ScheduledTick<?>> ticksPerPosition = new ObjectOpenCustomHashSet<>(ScheduledTick.UNIQUE_TICK_HASH);
|
||||||
|
+ private final Set<ScheduledTick<?>> ticksPerPosition = it.unimi.dsi.fastutil.objects.ObjectSets.synchronize(new ObjectOpenCustomHashSet<>(ScheduledTick.UNIQUE_TICK_HASH)); // DivineMC - Optimize level ticking
|
||||||
|
@Nullable
|
||||||
|
private BiConsumer<LevelChunkTicks<T>, ScheduledTick<T>> onTickAdded;
|
||||||
|
|
||||||
|
@@ -67,10 +67,18 @@ public class LevelChunkTicks<T> implements SerializableTickContainer<T>, TickCon
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ScheduledTick<T> poll() {
|
||||||
|
- ScheduledTick<T> scheduledTick = this.tickQueue.poll();
|
||||||
|
- if (scheduledTick != null) {
|
||||||
|
- this.ticksPerPosition.remove(scheduledTick); this.dirty = true; // Paper - rewrite chunk system
|
||||||
|
+ // DivineMC start - Optimize collections
|
||||||
|
+ ScheduledTick<T> scheduledTick = null;
|
||||||
|
+ try {
|
||||||
|
+ scheduledTick = this.tickQueue.poll();
|
||||||
|
+ if (scheduledTick != null) {
|
||||||
|
+ this.ticksPerPosition.remove(scheduledTick); this.dirty = true; // Paper - rewrite chunk system
|
||||||
|
+ }
|
||||||
|
+ } catch (Exception e) {
|
||||||
|
+ net.minecraft.server.MinecraftServer.LOGGER.error("Encountered caught exception when polling chunk ticks, blocking and returning null.", e);
|
||||||
|
+ return null;
|
||||||
|
}
|
||||||
|
+ // DivineMC end - Optimize collections
|
||||||
|
|
||||||
|
return scheduledTick;
|
||||||
|
}
|
||||||
|
@@ -83,6 +91,7 @@ public class LevelChunkTicks<T> implements SerializableTickContainer<T>, TickCon
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scheduleUnchecked(ScheduledTick<T> tick) {
|
||||||
|
+ if (tick == null) return; // DivineMC - Optimize level ticking
|
||||||
|
this.tickQueue.add(tick);
|
||||||
|
if (this.onTickAdded != null) {
|
||||||
|
this.onTickAdded.accept(this, tick);
|
||||||
|
@@ -124,6 +133,7 @@ public class LevelChunkTicks<T> implements SerializableTickContainer<T>, TickCon
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ScheduledTick<T> scheduledTick : this.tickQueue) {
|
||||||
|
+ if (scheduledTick == null) continue; // DivineMC - Optimize level ticking
|
||||||
|
list.add(scheduledTick.toSavedTick(gametime));
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/net/minecraft/world/ticks/LevelTicks.java b/net/minecraft/world/ticks/LevelTicks.java
|
||||||
|
index c7f9485191dc797de78e6524c5c2c737581ed838..14f2d0088cd9e6d4a2eb084439bab18bd365c41f 100644
|
||||||
|
--- a/net/minecraft/world/ticks/LevelTicks.java
|
||||||
|
+++ b/net/minecraft/world/ticks/LevelTicks.java
|
||||||
|
@@ -30,17 +30,20 @@ public class LevelTicks<T> implements LevelTickAccess<T> {
|
||||||
|
private static final Comparator<LevelChunkTicks<?>> CONTAINER_DRAIN_ORDER = (levelChunkTicks, levelChunkTicks1) -> ScheduledTick.INTRA_TICK_DRAIN_ORDER
|
||||||
|
.compare(levelChunkTicks.peek(), levelChunkTicks1.peek());
|
||||||
|
private final LongPredicate tickCheck;
|
||||||
|
- private final Long2ObjectMap<LevelChunkTicks<T>> allContainers = new Long2ObjectOpenHashMap<>();
|
||||||
|
- private final Long2LongMap nextTickForContainer = Util.make(new Long2LongOpenHashMap(), map -> map.defaultReturnValue(Long.MAX_VALUE));
|
||||||
|
- private final Queue<LevelChunkTicks<T>> containersToTick = new PriorityQueue<>(CONTAINER_DRAIN_ORDER);
|
||||||
|
- private final Queue<ScheduledTick<T>> toRunThisTick = new ArrayDeque<>();
|
||||||
|
+ // DivineMC start - Optimize collections
|
||||||
|
+ private final Long2ObjectMap<LevelChunkTicks<T>> allContainers = it.unimi.dsi.fastutil.longs.Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>());
|
||||||
|
+ private final java.util.Map<Long, Long> nextTickForContainer = new java.util.concurrent.ConcurrentHashMap<>();
|
||||||
|
+ private final Queue<LevelChunkTicks<T>> containersToTick = new java.util.concurrent.PriorityBlockingQueue<>(11, CONTAINER_DRAIN_ORDER);
|
||||||
|
+ private final Queue<ScheduledTick<T>> toRunThisTick = new java.util.concurrent.ConcurrentLinkedQueue<>();
|
||||||
|
+ // DivineMC end - Optimize collections
|
||||||
|
private final List<ScheduledTick<T>> alreadyRunThisTick = new ArrayList<>();
|
||||||
|
- private final Set<ScheduledTick<?>> toRunThisTickSet = new ObjectOpenCustomHashSet<>(ScheduledTick.UNIQUE_TICK_HASH);
|
||||||
|
+ private final Set<ScheduledTick<?>> toRunThisTickSet = com.google.common.collect.Sets.newConcurrentHashSet(); // DivineMC - Optimize level ticking
|
||||||
|
private final BiConsumer<LevelChunkTicks<T>, ScheduledTick<T>> chunkScheduleUpdater = (levelChunkTicks, scheduledTick) -> {
|
||||||
|
if (scheduledTick.equals(levelChunkTicks.peek())) {
|
||||||
|
this.updateContainerScheduling(scheduledTick);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
+ private final java.util.concurrent.atomic.AtomicInteger toRunThisTickCount = new java.util.concurrent.atomic.AtomicInteger(0); // DivineMC - Optimize level ticking
|
||||||
|
|
||||||
|
public LevelTicks(LongPredicate tickCheck) {
|
||||||
|
this.tickCheck = tickCheck;
|
||||||
|
@@ -90,12 +93,14 @@ public class LevelTicks<T> implements LevelTickAccess<T> {
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sortContainersToTick(long gameTime) {
|
||||||
|
- ObjectIterator<Entry> objectIterator = Long2LongMaps.fastIterator(this.nextTickForContainer);
|
||||||
|
+ java.util.Iterator<java.util.Map.Entry<Long, Long>> objectIterator = this.nextTickForContainer.entrySet().iterator(); // DivineMC - Optimize level ticking
|
||||||
|
|
||||||
|
while (objectIterator.hasNext()) {
|
||||||
|
- Entry entry = objectIterator.next();
|
||||||
|
- long longKey = entry.getLongKey();
|
||||||
|
- long longValue = entry.getLongValue();
|
||||||
|
+ // DivineMC start - Optimize collections
|
||||||
|
+ java.util.Map.Entry<Long, Long> entry = objectIterator.next();
|
||||||
|
+ long longKey = entry.getKey();
|
||||||
|
+ long longValue = entry.getValue();
|
||||||
|
+ // DivineMC end - Optimize collections
|
||||||
|
if (longValue <= gameTime) {
|
||||||
|
LevelChunkTicks<T> levelChunkTicks = this.allContainers.get(longKey);
|
||||||
|
if (levelChunkTicks == null) {
|
||||||
|
@@ -162,16 +167,19 @@ public class LevelTicks<T> implements LevelTickAccess<T> {
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scheduleForThisTick(ScheduledTick<T> tick) {
|
||||||
|
+ if (tick == null) return; // DivineMC - Optimize level ticking
|
||||||
|
this.toRunThisTick.add(tick);
|
||||||
|
+ this.toRunThisTickCount.incrementAndGet(); // DivineMC - Optimize level ticking
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canScheduleMoreTicks(int maxAllowedTicks) {
|
||||||
|
- return this.toRunThisTick.size() < maxAllowedTicks;
|
||||||
|
+ return this.toRunThisTickCount.get() < maxAllowedTicks; // DivineMC - Optimize level ticking
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runCollectedTicks(BiConsumer<BlockPos, T> ticker) {
|
||||||
|
while (!this.toRunThisTick.isEmpty()) {
|
||||||
|
ScheduledTick<T> scheduledTick = this.toRunThisTick.poll();
|
||||||
|
+ this.toRunThisTickCount.decrementAndGet(); // DivineMC - Optimize level ticking
|
||||||
|
if (!this.toRunThisTickSet.isEmpty()) {
|
||||||
|
this.toRunThisTickSet.remove(scheduledTick);
|
||||||
|
}
|
||||||
|
@@ -182,7 +190,7 @@ public class LevelTicks<T> implements LevelTickAccess<T> {
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanupAfterTick() {
|
||||||
|
- this.toRunThisTick.clear();
|
||||||
|
+ this.toRunThisTickCount.set(0); // DivineMC - Optimize level ticking
|
||||||
|
this.containersToTick.clear();
|
||||||
|
this.alreadyRunThisTick.clear();
|
||||||
|
this.toRunThisTickSet.clear();
|
||||||
@@ -0,0 +1,480 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||||
|
Date: Mon, 11 Aug 2025 02:42:19 +0300
|
||||||
|
Subject: [PATCH] Optimize Moonrise
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
|
||||||
|
index 93272808d94e81d31af728ebe85df9a2bc7aedab..b47be4b838f4c7f6c3fb62e4e18105c6b4972016 100644
|
||||||
|
--- a/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
|
||||||
|
+++ b/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
|
||||||
|
@@ -59,7 +59,7 @@ public final class NearbyPlayers {
|
||||||
|
public static final int GENERAL_REALLY_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_REALLY_SMALL_VIEW_DISTANCE << 4);
|
||||||
|
|
||||||
|
private final ServerLevel world;
|
||||||
|
- private final Reference2ReferenceOpenHashMap<ServerPlayer, TrackedPlayer[]> players = new Reference2ReferenceOpenHashMap<>();
|
||||||
|
+ private final it.unimi.dsi.fastutil.objects.Reference2ReferenceMap<ServerPlayer, TrackedPlayer[]> players = it.unimi.dsi.fastutil.objects.Reference2ReferenceMaps.synchronize(new Reference2ReferenceOpenHashMap<>()); // DivineMC - Optimize collections
|
||||||
|
// DivineMC start - Multithreaded Tracker
|
||||||
|
private final it.unimi.dsi.fastutil.longs.Long2ReferenceMap<TrackedChunk> byChunk;
|
||||||
|
{
|
||||||
|
@@ -70,10 +70,10 @@ public final class NearbyPlayers {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// DivineMC end - Multithreaded Tracker
|
||||||
|
- private final Long2ReferenceOpenHashMap<ReferenceList<ServerPlayer>>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES];
|
||||||
|
+ private final it.unimi.dsi.fastutil.longs.Long2ReferenceMap<ReferenceList<ServerPlayer>>[] directByChunk = new it.unimi.dsi.fastutil.longs.Long2ReferenceMap[TOTAL_MAP_TYPES]; // DivineMC - Optimize collections
|
||||||
|
{
|
||||||
|
for (int i = 0; i < this.directByChunk.length; ++i) {
|
||||||
|
- this.directByChunk[i] = new Long2ReferenceOpenHashMap<>();
|
||||||
|
+ this.directByChunk[i] = it.unimi.dsi.fastutil.longs.Long2ReferenceMaps.synchronize(new Long2ReferenceOpenHashMap<>()); // DivineMC - Optimize collections
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
||||||
|
index 57fec1f9a210d2ecb74ff7b05cec790ae77f9178..4d0e904d7d7659b24a883893cef167f3e80dfa36 100644
|
||||||
|
--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
||||||
|
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
||||||
|
@@ -73,37 +73,51 @@ public final class ChunkHolderManager {
|
||||||
|
private static final long NO_TIMEOUT_MARKER = Long.MIN_VALUE;
|
||||||
|
public final ReentrantAreaLock ticketLockArea;
|
||||||
|
|
||||||
|
- private final ConcurrentLong2ReferenceChainedHashTable<SortedArraySet<Ticket>> tickets = new ConcurrentLong2ReferenceChainedHashTable<>();
|
||||||
|
- private final ConcurrentLong2ReferenceChainedHashTable<Long2IntOpenHashMap> sectionToChunkToExpireCount = new ConcurrentLong2ReferenceChainedHashTable<>();
|
||||||
|
+ // DivineMC start - Optimize Moonrise
|
||||||
|
+ private final ConcurrentLong2ReferenceChainedHashTable<SortedArraySet<Ticket>> tickets = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(20, 0.9F);
|
||||||
|
+ private final ConcurrentLong2ReferenceChainedHashTable<Long2IntOpenHashMap> sectionToChunkToExpireCount = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(20, 0.9F);
|
||||||
|
+ // DivineMC end - Optimize Moonrise
|
||||||
|
final ChunkUnloadQueue unloadQueue;
|
||||||
|
|
||||||
|
- private final ConcurrentLong2ReferenceChainedHashTable<NewChunkHolder> chunkHolders = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(16384, 0.25f);
|
||||||
|
+ private final ConcurrentLong2ReferenceChainedHashTable<NewChunkHolder> chunkHolders = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(20, 0.9F); // DivineMC - Optimize Moonrise
|
||||||
|
private final ServerLevel world;
|
||||||
|
private final ChunkTaskScheduler taskScheduler;
|
||||||
|
private long currentTick;
|
||||||
|
|
||||||
|
- private final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = new ArrayDeque<>();
|
||||||
|
- private final MultiThreadedQueue<NewChunkHolder> offThreadPendingFullLoadUpdate = new MultiThreadedQueue<>();
|
||||||
|
- private final ObjectRBTreeSet<NewChunkHolder> autoSaveQueue = new ObjectRBTreeSet<>((final NewChunkHolder c1, final NewChunkHolder c2) -> {
|
||||||
|
- if (c1 == c2) {
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
+ // DivineMC start - Optimize Moonrise
|
||||||
|
+ public static class LevelHolderData {
|
||||||
|
+ private final java.util.concurrent.ConcurrentLinkedDeque<NewChunkHolder> pendingFullLoadUpdate = new java.util.concurrent.ConcurrentLinkedDeque<>();
|
||||||
|
+ private final MultiThreadedQueue<NewChunkHolder> offThreadPendingFullLoadUpdate = new MultiThreadedQueue<>();
|
||||||
|
+ private final ObjectRBTreeSet<NewChunkHolder> autoSaveQueue = new ObjectRBTreeSet<>((final NewChunkHolder c1, final NewChunkHolder c2) -> {
|
||||||
|
+ if (c1 == c2) {
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- final int saveTickCompare = Long.compare(c1.lastAutoSave, c2.lastAutoSave);
|
||||||
|
+ final int saveTickCompare = Long.compare(c1.lastAutoSave, c2.lastAutoSave);
|
||||||
|
|
||||||
|
- if (saveTickCompare != 0) {
|
||||||
|
- return saveTickCompare;
|
||||||
|
- }
|
||||||
|
+ if (saveTickCompare != 0) {
|
||||||
|
+ return saveTickCompare;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ final long coord1 = CoordinateUtils.getChunkKey(c1.chunkX, c1.chunkZ);
|
||||||
|
+ final long coord2 = CoordinateUtils.getChunkKey(c2.chunkX, c2.chunkZ);
|
||||||
|
|
||||||
|
- final long coord1 = CoordinateUtils.getChunkKey(c1.chunkX, c1.chunkZ);
|
||||||
|
- final long coord2 = CoordinateUtils.getChunkKey(c2.chunkX, c2.chunkZ);
|
||||||
|
+ if (coord1 == coord2) {
|
||||||
|
+ throw new IllegalStateException("Duplicate chunkholder in auto save queue");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return Long.compare(coord1, coord2);
|
||||||
|
+ });
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (coord1 == coord2) {
|
||||||
|
- throw new IllegalStateException("Duplicate chunkholder in auto save queue");
|
||||||
|
+ public LevelHolderData getData() {
|
||||||
|
+ if (this.world == null) {
|
||||||
|
+ throw new RuntimeException("World was null!");
|
||||||
|
}
|
||||||
|
|
||||||
|
- return Long.compare(coord1, coord2);
|
||||||
|
- });
|
||||||
|
+ return world.chunkHolderData;
|
||||||
|
+ }
|
||||||
|
+ // DivineMC end - Optimize Moonrise
|
||||||
|
|
||||||
|
private final ConcurrentLong2ReferenceChainedHashTable<Long2IntOpenHashMap> ticketCounters = new ConcurrentLong2ReferenceChainedHashTable<>();
|
||||||
|
|
||||||
|
@@ -226,26 +240,29 @@ public final class ChunkHolderManager {
|
||||||
|
this.taskScheduler.setShutdown(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
- void ensureInAutosave(final NewChunkHolder holder) {
|
||||||
|
- if (!this.autoSaveQueue.contains(holder)) {
|
||||||
|
+ // DivineMC start - Optimize Moonrise
|
||||||
|
+ synchronized void ensureInAutosave(final NewChunkHolder holder) {
|
||||||
|
+ final LevelHolderData data = getData();
|
||||||
|
+ if (!data.autoSaveQueue.contains(holder)) {
|
||||||
|
holder.lastAutoSave = this.currentTick;
|
||||||
|
- this.autoSaveQueue.add(holder);
|
||||||
|
+ data.autoSaveQueue.add(holder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- public void autoSave() {
|
||||||
|
+ public synchronized void autoSave() {
|
||||||
|
+ final LevelHolderData data = getData();
|
||||||
|
final List<NewChunkHolder> reschedule = new ArrayList<>();
|
||||||
|
final long currentTick = this.currentTick;
|
||||||
|
final long maxSaveTime = currentTick - Math.max(1L, PlatformHooks.get().configAutoSaveInterval(this.world));
|
||||||
|
final int maxToSave = PlatformHooks.get().configMaxAutoSavePerTick(this.world);
|
||||||
|
- for (int autoSaved = 0; autoSaved < maxToSave && !this.autoSaveQueue.isEmpty();) {
|
||||||
|
- final NewChunkHolder holder = this.autoSaveQueue.first();
|
||||||
|
+ for (int autoSaved = 0; autoSaved < maxToSave && !data.autoSaveQueue.isEmpty();) {
|
||||||
|
+ final NewChunkHolder holder = data.autoSaveQueue.first();
|
||||||
|
|
||||||
|
if (holder.lastAutoSave > maxSaveTime) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- this.autoSaveQueue.remove(holder);
|
||||||
|
+ data.autoSaveQueue.remove(holder);
|
||||||
|
|
||||||
|
holder.lastAutoSave = currentTick;
|
||||||
|
if (holder.save(false) != null) {
|
||||||
|
@@ -259,10 +276,11 @@ public final class ChunkHolderManager {
|
||||||
|
|
||||||
|
for (final NewChunkHolder holder : reschedule) {
|
||||||
|
if (holder.getChunkStatus().isOrAfter(FullChunkStatus.FULL)) {
|
||||||
|
- this.autoSaveQueue.add(holder);
|
||||||
|
+ data.autoSaveQueue.add(holder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ // DivineMC end - Optimize Moonrise
|
||||||
|
|
||||||
|
public void saveAllChunks(final boolean flush, final boolean shutdown, final boolean logProgress) {
|
||||||
|
final List<NewChunkHolder> holders = this.getChunkHolders();
|
||||||
|
@@ -461,8 +479,8 @@ public final class ChunkHolderManager {
|
||||||
|
final Long2ObjectOpenHashMap<SortedArraySet<Ticket>> ret = new Long2ObjectOpenHashMap<>();
|
||||||
|
final Long2ObjectOpenHashMap<LongArrayList> sections = new Long2ObjectOpenHashMap<>();
|
||||||
|
final int sectionShift = this.taskScheduler.getChunkSystemLockShift();
|
||||||
|
- for (final PrimitiveIterator.OfLong iterator = this.tickets.keyIterator(); iterator.hasNext();) {
|
||||||
|
- final long coord = iterator.nextLong();
|
||||||
|
+ for (final Iterator<Long> iterator = this.tickets.keyIterator(); iterator.hasNext();) { // DivineMC - Optimize Moonrise
|
||||||
|
+ final long coord = iterator.next(); // DivineMC - Optimize Moonrise
|
||||||
|
sections.computeIfAbsent(
|
||||||
|
CoordinateUtils.getChunkKey(
|
||||||
|
CoordinateUtils.getChunkX(coord) >> sectionShift,
|
||||||
|
@@ -559,7 +577,7 @@ public final class ChunkHolderManager {
|
||||||
|
chunkZ >> sectionShift
|
||||||
|
);
|
||||||
|
|
||||||
|
- this.sectionToChunkToExpireCount.computeIfAbsent(sectionKey, (final long keyInMap) -> {
|
||||||
|
+ this.sectionToChunkToExpireCount.computeIfAbsent(sectionKey, (keyInMap) -> { // DivineMC - Optimize Moonrise
|
||||||
|
return new Long2IntOpenHashMap();
|
||||||
|
}).addTo(chunkKey, 1);
|
||||||
|
}
|
||||||
|
@@ -603,8 +621,8 @@ public final class ChunkHolderManager {
|
||||||
|
|
||||||
|
final ReentrantAreaLock.Node ticketLock = lock ? this.ticketLockArea.lock(chunkX, chunkZ) : null;
|
||||||
|
try {
|
||||||
|
- final SortedArraySet<Ticket> ticketsAtChunk = this.tickets.computeIfAbsent(chunk, (final long keyInMap) -> {
|
||||||
|
- return (SortedArraySet)SortedArraySet.create(4);
|
||||||
|
+ final SortedArraySet<Ticket> ticketsAtChunk = this.tickets.computeIfAbsent(chunk, (keyInMap) -> { // DivineMC - Optimize Moonrise
|
||||||
|
+ return SortedArraySet.create(4); // DivineMC - Optimize Moonrise
|
||||||
|
});
|
||||||
|
|
||||||
|
final int levelBefore = getTicketLevelAt(ticketsAtChunk);
|
||||||
|
@@ -784,8 +802,8 @@ public final class ChunkHolderManager {
|
||||||
|
|
||||||
|
final Long2ObjectOpenHashMap<LongArrayList> sections = new Long2ObjectOpenHashMap<>();
|
||||||
|
final int sectionShift = this.taskScheduler.getChunkSystemLockShift();
|
||||||
|
- for (final PrimitiveIterator.OfLong iterator = this.tickets.keyIterator(); iterator.hasNext();) {
|
||||||
|
- final long coord = iterator.nextLong();
|
||||||
|
+ for (final Iterator<Long> iterator = this.tickets.keyIterator(); iterator.hasNext();) { // DivineMC - Optimize Moonrise
|
||||||
|
+ final long coord = iterator.next(); // DivineMC - Optimize Moonrise
|
||||||
|
sections.computeIfAbsent(
|
||||||
|
CoordinateUtils.getChunkKey(
|
||||||
|
CoordinateUtils.getChunkX(coord) >> sectionShift,
|
||||||
|
@@ -836,8 +854,8 @@ public final class ChunkHolderManager {
|
||||||
|
final List<ChunkProgressionTask> scheduledTasks = new ArrayList<>();
|
||||||
|
final List<NewChunkHolder> changedFullStatus = new ArrayList<>();
|
||||||
|
|
||||||
|
- for (final PrimitiveIterator.OfLong iterator = this.sectionToChunkToExpireCount.keyIterator(); iterator.hasNext();) {
|
||||||
|
- final long sectionKey = iterator.nextLong();
|
||||||
|
+ for (final Iterator<Long> iterator = this.sectionToChunkToExpireCount.keyIterator(); iterator.hasNext();) { // DivineMC - Optimize Moonrise
|
||||||
|
+ final long sectionKey = iterator.next(); // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
if (!this.sectionToChunkToExpireCount.containsKey(sectionKey)) {
|
||||||
|
// removed concurrently
|
||||||
|
@@ -1145,18 +1163,18 @@ public final class ChunkHolderManager {
|
||||||
|
if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && !TickThread.isTickThreadFor(world) || !TickThread.isTickThread()) { // DivineMC - Parallel world ticking
|
||||||
|
// These will be handled on the next ServerChunkCache$MainThreadExecutor#pollTask, as it runs the distance manager update
|
||||||
|
// which will invoke processTicketUpdates
|
||||||
|
- this.offThreadPendingFullLoadUpdate.addAll(changedFullStatus);
|
||||||
|
+ this.getData().offThreadPendingFullLoadUpdate.addAll(changedFullStatus); // DivineMC - Optimize Moonrise
|
||||||
|
} else {
|
||||||
|
- final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = this.pendingFullLoadUpdate;
|
||||||
|
+ final java.util.Deque<NewChunkHolder> pendingFullLoadUpdate = this.getData().pendingFullLoadUpdate; // DivineMC - Optimize Moonrise
|
||||||
|
for (int i = 0, len = changedFullStatus.size(); i < len; ++i) {
|
||||||
|
pendingFullLoadUpdate.add(changedFullStatus.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- private void removeChunkHolder(final NewChunkHolder holder) {
|
||||||
|
+ private synchronized void removeChunkHolder(final NewChunkHolder holder) { // DivineMC - Optimize Moonrise
|
||||||
|
holder.onUnload();
|
||||||
|
- this.autoSaveQueue.remove(holder);
|
||||||
|
+ this.getData().autoSaveQueue.remove(holder); // DivineMC - Optimize Moonrise
|
||||||
|
PlatformHooks.get().onChunkHolderDelete(this.world, holder.vanillaChunkHolder);
|
||||||
|
this.chunkHolders.remove(CoordinateUtils.getChunkKey(holder.chunkX, holder.chunkZ));
|
||||||
|
}
|
||||||
|
@@ -1320,6 +1338,27 @@ public final class ChunkHolderManager {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // DivineMC start - Optimize Moonrise
|
||||||
|
+ public final java.util.Set<Long> blockTickingChunkHolders = java.util.Collections.synchronizedSet(new org.agrona.collections.ObjectHashSet<>(10, 0.88f, true));
|
||||||
|
+ public final java.util.Set<Long> entityTickingChunkHolders = java.util.Collections.synchronizedSet(new org.agrona.collections.ObjectHashSet<>(10, 0.88f, true));
|
||||||
|
+
|
||||||
|
+ public void markBlockTicking(@org.jetbrains.annotations.NotNull NewChunkHolder newChunkHolder) {
|
||||||
|
+ this.blockTickingChunkHolders.add(newChunkHolder.getCachedLongPos());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public void markNonBlockTickingIfPossible(@org.jetbrains.annotations.NotNull NewChunkHolder newChunkHolder) {
|
||||||
|
+ this.blockTickingChunkHolders.remove(newChunkHolder.getCachedLongPos());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public void markEntityTicking(@org.jetbrains.annotations.NotNull NewChunkHolder newChunkHolder) {
|
||||||
|
+ this.entityTickingChunkHolders.add(newChunkHolder.getCachedLongPos());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public void markNonEntityTickingIfPossible(@org.jetbrains.annotations.NotNull NewChunkHolder newChunkHolder) {
|
||||||
|
+ this.entityTickingChunkHolders.remove(newChunkHolder.getCachedLongPos());
|
||||||
|
+ }
|
||||||
|
+ // DivineMC end - Optimize Moonrise
|
||||||
|
+
|
||||||
|
public enum TicketOperationType {
|
||||||
|
ADD, REMOVE, ADD_IF_REMOVED, ADD_AND_REMOVE
|
||||||
|
}
|
||||||
|
@@ -1479,8 +1518,10 @@ public final class ChunkHolderManager {
|
||||||
|
|
||||||
|
// only call on tick thread
|
||||||
|
private void processOffThreadFullUpdates() {
|
||||||
|
- final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = this.pendingFullLoadUpdate;
|
||||||
|
- final MultiThreadedQueue<NewChunkHolder> offThreadPendingFullLoadUpdate = this.offThreadPendingFullLoadUpdate;
|
||||||
|
+ // DivineMC start - Optimize Moonrise
|
||||||
|
+ final java.util.concurrent.ConcurrentLinkedDeque<NewChunkHolder> pendingFullLoadUpdate = this.getData().pendingFullLoadUpdate;
|
||||||
|
+ final MultiThreadedQueue<NewChunkHolder> offThreadPendingFullLoadUpdate = this.getData().offThreadPendingFullLoadUpdate;
|
||||||
|
+ // DivineMC end - Optimize Moonrise
|
||||||
|
|
||||||
|
NewChunkHolder toUpdate;
|
||||||
|
while ((toUpdate = offThreadPendingFullLoadUpdate.poll()) != null) {
|
||||||
|
@@ -1492,7 +1533,7 @@ public final class ChunkHolderManager {
|
||||||
|
private boolean processPendingFullUpdate() {
|
||||||
|
this.processOffThreadFullUpdates();
|
||||||
|
|
||||||
|
- final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = this.pendingFullLoadUpdate;
|
||||||
|
+ final java.util.Deque<NewChunkHolder> pendingFullLoadUpdate = this.getData().pendingFullLoadUpdate; // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
boolean ret = false;
|
||||||
|
|
||||||
|
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java
|
||||||
|
index 2cc0e7c72d2b2e562452138f2b41fd1dcaf0570a..affa0dac8633ce3a43c9609888ed96d0aabdab5e 100644
|
||||||
|
--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java
|
||||||
|
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java
|
||||||
|
@@ -646,12 +646,20 @@ public final class NewChunkHolder {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final ChunkHolder vanillaChunkHolder;
|
||||||
|
+ // DivineMC start - Optimize Moonrise
|
||||||
|
+ private final long cachedLongPos;
|
||||||
|
+
|
||||||
|
+ public long getCachedLongPos() {
|
||||||
|
+ return cachedLongPos;
|
||||||
|
+ }
|
||||||
|
+ // DivineMC end - Optimize Moonrise
|
||||||
|
|
||||||
|
public NewChunkHolder(final ServerLevel world, final int chunkX, final int chunkZ, final ChunkTaskScheduler scheduler) {
|
||||||
|
this.world = world;
|
||||||
|
this.chunkX = chunkX;
|
||||||
|
this.chunkZ = chunkZ;
|
||||||
|
this.scheduler = scheduler;
|
||||||
|
+ this.cachedLongPos = ((long)chunkZ << 32) | (chunkX & 0xFFFFFFFFL); // DivineMC - Optimize Moonrise
|
||||||
|
this.vanillaChunkHolder = new ChunkHolder(
|
||||||
|
new ChunkPos(chunkX, chunkZ), ChunkHolderManager.MAX_TICKET_LEVEL, world,
|
||||||
|
world.getLightEngine(), null, world.getChunkSource().chunkMap
|
||||||
|
@@ -792,9 +800,11 @@ public final class NewChunkHolder {
|
||||||
|
|
||||||
|
// note: these are completed with null to indicate that no write occurred
|
||||||
|
// they are also completed with null to indicate a null write occurred
|
||||||
|
- private UnloadTask chunkDataUnload;
|
||||||
|
- private UnloadTask entityDataUnload;
|
||||||
|
- private UnloadTask poiDataUnload;
|
||||||
|
+ // DivineMC start - Optimize Moonrise
|
||||||
|
+ private volatile UnloadTask chunkDataUnload;
|
||||||
|
+ private volatile UnloadTask entityDataUnload;
|
||||||
|
+ private volatile UnloadTask poiDataUnload;
|
||||||
|
+ // DivineMC end - Optimize Moonrise
|
||||||
|
|
||||||
|
public static final record UnloadTask(CallbackCompletable<CompoundTag> completable, PrioritisedExecutor.PrioritisedTask task,
|
||||||
|
LazyRunnable toRun) {}
|
||||||
|
@@ -879,7 +889,11 @@ public final class NewChunkHolder {
|
||||||
|
MoonriseRegionFileIO.scheduleSave(this.world, this.chunkX, this.chunkZ, data, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
- this.getUnloadTask(type).completable().complete(data);
|
||||||
|
+ // DivineMC start - Optimize Moonrise
|
||||||
|
+ UnloadTask task = this.getUnloadTask(type);
|
||||||
|
+ if (task == null) return;
|
||||||
|
+ task.completable().complete(data);
|
||||||
|
+ // DivineMC end - Optimize Moonrise
|
||||||
|
final ReentrantAreaLock.Node schedulingLock = this.scheduler.schedulingLockArea.lock(this.chunkX, this.chunkZ);
|
||||||
|
try {
|
||||||
|
// can only write to these fields while holding the schedule lock
|
||||||
|
@@ -1192,6 +1206,7 @@ public final class NewChunkHolder {
|
||||||
|
for (int dz = -NEIGHBOUR_RADIUS; dz <= NEIGHBOUR_RADIUS; ++dz) {
|
||||||
|
for (int dx = -NEIGHBOUR_RADIUS; dx <= NEIGHBOUR_RADIUS; ++dx) {
|
||||||
|
final NewChunkHolder holder = (dx | dz) == 0 ? this : this.scheduler.chunkHolderManager.getChunkHolder(dx + this.chunkX, dz + this.chunkZ);
|
||||||
|
+ if (holder == null) continue; // DivineMC - Optimize Moonrise
|
||||||
|
if (loaded) {
|
||||||
|
if (holder.setNeighbourFullLoaded(-dx, -dz)) {
|
||||||
|
changedFullStatus.add(holder);
|
||||||
|
@@ -1216,6 +1231,19 @@ public final class NewChunkHolder {
|
||||||
|
|
||||||
|
private void updateCurrentState(final FullChunkStatus to) {
|
||||||
|
this.currentFullChunkStatus = to;
|
||||||
|
+ // DivineMC start - Optimize Moonrise
|
||||||
|
+ if (to.isOrAfter(FullChunkStatus.BLOCK_TICKING)) {
|
||||||
|
+ this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.markBlockTicking(this);
|
||||||
|
+ } else {
|
||||||
|
+ this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.markNonBlockTickingIfPossible(this);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (to.isOrAfter(FullChunkStatus.ENTITY_TICKING)) {
|
||||||
|
+ this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.markEntityTicking(this);
|
||||||
|
+ } else {
|
||||||
|
+ this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.markNonEntityTickingIfPossible(this);
|
||||||
|
+ }
|
||||||
|
+ // DivineMC end - Optimize Moonrise
|
||||||
|
}
|
||||||
|
|
||||||
|
// only to be called on the main thread, no locks need to be held
|
||||||
|
@@ -1350,7 +1378,7 @@ public final class NewChunkHolder {
|
||||||
|
return this.requestedGenStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
- private final Reference2ObjectOpenHashMap<ChunkStatus, List<Consumer<ChunkAccess>>> statusWaiters = new Reference2ObjectOpenHashMap<>();
|
||||||
|
+ private final Reference2ObjectMap<ChunkStatus, List<Consumer<ChunkAccess>>> statusWaiters = it.unimi.dsi.fastutil.objects.Reference2ObjectMaps.synchronize(new Reference2ObjectOpenHashMap<>()); // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
void addStatusConsumer(final ChunkStatus status, final Consumer<ChunkAccess> consumer) {
|
||||||
|
this.statusWaiters.computeIfAbsent(status, (final ChunkStatus keyInMap) -> {
|
||||||
|
@@ -1396,7 +1424,7 @@ public final class NewChunkHolder {
|
||||||
|
}, Priority.HIGHEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
- private final Reference2ObjectOpenHashMap<FullChunkStatus, List<Consumer<LevelChunk>>> fullStatusWaiters = new Reference2ObjectOpenHashMap<>();
|
||||||
|
+ private final Reference2ObjectMap<FullChunkStatus, List<Consumer<LevelChunk>>> fullStatusWaiters = it.unimi.dsi.fastutil.objects.Reference2ObjectMaps.synchronize(new Reference2ObjectOpenHashMap<>()); // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
void addFullStatusConsumer(final FullChunkStatus status, final Consumer<LevelChunk> consumer) {
|
||||||
|
this.fullStatusWaiters.computeIfAbsent(status, (final FullChunkStatus keyInMap) -> {
|
||||||
|
diff --git a/ca/spottedleaf/moonrise/patches/starlight/light/SWMRNibbleArray.java b/ca/spottedleaf/moonrise/patches/starlight/light/SWMRNibbleArray.java
|
||||||
|
index 4ca68a903e67606fc4ef0bfa9862a73797121c8b..1ac37db68341672481cd4bbdf7bab90572c35453 100644
|
||||||
|
--- a/ca/spottedleaf/moonrise/patches/starlight/light/SWMRNibbleArray.java
|
||||||
|
+++ b/ca/spottedleaf/moonrise/patches/starlight/light/SWMRNibbleArray.java
|
||||||
|
@@ -325,7 +325,7 @@ public final class SWMRNibbleArray {
|
||||||
|
}
|
||||||
|
|
||||||
|
// operation type: updating
|
||||||
|
- public boolean updateVisible() {
|
||||||
|
+ public synchronized boolean updateVisible() { // DivineMC - Optimize Moonrise
|
||||||
|
if (!this.isDirty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
diff --git a/net/minecraft/server/level/DistanceManager.java b/net/minecraft/server/level/DistanceManager.java
|
||||||
|
index 50bc5b940812432bc472e5b272582efb8bbfc7a7..0bece4ed69b332174cbe37f82df1f7da9276d591 100644
|
||||||
|
--- a/net/minecraft/server/level/DistanceManager.java
|
||||||
|
+++ b/net/minecraft/server/level/DistanceManager.java
|
||||||
|
@@ -127,15 +127,13 @@ public abstract class DistanceManager implements ca.spottedleaf.moonrise.patches
|
||||||
|
|
||||||
|
public boolean inEntityTickingRange(long chunkPos) {
|
||||||
|
// Paper start - rewrite chunk system
|
||||||
|
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkHolderManager().getChunkHolder(chunkPos);
|
||||||
|
- return chunkHolder != null && chunkHolder.isEntityTickingReady();
|
||||||
|
+ return this.moonrise$getChunkHolderManager().entityTickingChunkHolders.contains(chunkPos); // DivineMC - Optimize Moonrise
|
||||||
|
// Paper end - rewrite chunk system
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean inBlockTickingRange(long chunkPos) {
|
||||||
|
// Paper start - rewrite chunk system
|
||||||
|
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkHolderManager().getChunkHolder(chunkPos);
|
||||||
|
- return chunkHolder != null && chunkHolder.isTickingReady();
|
||||||
|
+ return this.moonrise$getChunkHolderManager().blockTickingChunkHolders.contains(chunkPos); // DivineMC - Optimize Moonrise
|
||||||
|
// Paper end - rewrite chunk system
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
||||||
|
index 440bd8f16664fdc29db69b92f2c856dd7cc4ffd1..0abfd610caf529952fee857d881920a5ddad8ed3 100644
|
||||||
|
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||||
|
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||||
|
@@ -667,8 +667,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||||
|
|
||||||
|
public boolean isPositionTicking(long chunkPos) {
|
||||||
|
// Paper start - rewrite chunk system
|
||||||
|
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder newChunkHolder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkPos);
|
||||||
|
- return newChunkHolder != null && newChunkHolder.isTickingReady();
|
||||||
|
+ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.blockTickingChunkHolders.contains(chunkPos); // DivineMC - Optimize Moonrise
|
||||||
|
// Paper end - rewrite chunk system
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
|
index 4934ce03ac533d9c60674632cdac6621e62f6b44..b50afea7c2e4c61a3df196e74afd8f82b30aca8a 100644
|
||||||
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
|
@@ -179,6 +179,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
|
public final ServerChunkCache chunkSource;
|
||||||
|
private final MinecraftServer server;
|
||||||
|
public final net.minecraft.world.level.storage.PrimaryLevelData serverLevelData; // CraftBukkit - type
|
||||||
|
+ public final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager.LevelHolderData chunkHolderData; // DivineMC - Optimize Moonrise
|
||||||
|
private int lastSpawnChunkRadius;
|
||||||
|
final EntityTickList entityTickList = new EntityTickList(this); // DivineMC - Parallel world ticking
|
||||||
|
private final ServerWaypointManager waypointManager;
|
||||||
|
@@ -691,6 +692,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
|
// Paper start - rewrite chunk system
|
||||||
|
this.moonrise$setEntityLookup(new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup((ServerLevel)(Object)this, ((ServerLevel)(Object)this).new EntityCallbacks()));
|
||||||
|
this.chunkTaskScheduler = new ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler((ServerLevel)(Object)this);
|
||||||
|
+ this.chunkHolderData = new ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager.LevelHolderData(); // DivineMC - Optimize Moonrise
|
||||||
|
this.entityDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.EntityDataController(
|
||||||
|
new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.EntityDataController.EntityRegionFileStorage(
|
||||||
|
new RegionStorageInfo(levelStorageAccess.getLevelId(), dimension, "entities"),
|
||||||
|
@@ -846,8 +848,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
|
@Override
|
||||||
|
public boolean shouldTickBlocksAt(long chunkPos) {
|
||||||
|
// Paper start - rewrite chunk system
|
||||||
|
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder holder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkPos);
|
||||||
|
- return holder != null && holder.isTickingReady();
|
||||||
|
+ return this.moonrise$getChunkTaskScheduler().chunkHolderManager.blockTickingChunkHolders.contains(chunkPos); // DivineMC - Optimize Moonrise
|
||||||
|
// Paper end - rewrite chunk system
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2584,16 +2585,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
|
|
||||||
|
public boolean isPositionTickingWithEntitiesLoaded(long chunkPos) {
|
||||||
|
// Paper start - rewrite chunk system
|
||||||
|
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkPos);
|
||||||
|
- // isTicking implies the chunk is loaded, and the chunk is loaded now implies the entities are loaded
|
||||||
|
- return chunkHolder != null && chunkHolder.isTickingReady();
|
||||||
|
+ return this.moonrise$getChunkTaskScheduler().chunkHolderManager.blockTickingChunkHolders.contains(chunkPos); // DivineMC - Optimize Moonrise
|
||||||
|
// Paper end - rewrite chunk system
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPositionEntityTicking(BlockPos pos) {
|
||||||
|
// Paper start - rewrite chunk system
|
||||||
|
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(pos));
|
||||||
|
- return chunkHolder != null && chunkHolder.isEntityTickingReady();
|
||||||
|
+ return this.moonrise$getChunkTaskScheduler().chunkHolderManager.entityTickingChunkHolders.contains(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(pos)); // DivineMC - Optimize Moonrise
|
||||||
|
// Paper end - rewrite chunk system
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
--- a/net/minecraft/world/ticks/LevelTicks.java
|
|
||||||
+++ b/net/minecraft/world/ticks/LevelTicks.java
|
|
||||||
@@ -191,7 +_,6 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cleanupAfterTick() {
|
|
||||||
- this.toRunThisTick.clear();
|
|
||||||
this.containersToTick.clear();
|
|
||||||
this.alreadyRunThisTick.clear();
|
|
||||||
this.toRunThisTickSet.clear();
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
|
||||||
Date: Wed, 9 Jul 2025 03:37:51 +0300
|
|
||||||
Subject: [PATCH] Rewrite ReferenceList
|
|
||||||
|
|
||||||
|
|
||||||
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java
|
|
||||||
index 2e876b918672e8ef3b5197b7e6b1597247fdeaa1..94232d9ab2b1b064c032d9710734f6fbcdb52e10 100644
|
|
||||||
--- a/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java
|
|
||||||
+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java
|
|
||||||
@@ -1,142 +1,26 @@
|
|
||||||
package ca.spottedleaf.moonrise.common.list;
|
|
||||||
|
|
||||||
-import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
|
|
||||||
-import java.util.Arrays;
|
|
||||||
-import java.util.Iterator;
|
|
||||||
-import java.util.NoSuchElementException;
|
|
||||||
+// DivineMC start - Rewrite ReferenceList
|
|
||||||
+import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
|
|
||||||
+import it.unimi.dsi.fastutil.objects.ReferenceLists;
|
|
||||||
|
|
||||||
-public final class ReferenceList<E> implements Iterable<E> {
|
|
||||||
-
|
|
||||||
- private static final Object[] EMPTY_LIST = new Object[0];
|
|
||||||
-
|
|
||||||
- private final Reference2IntOpenHashMap<E> referenceToIndex;
|
|
||||||
- private E[] references;
|
|
||||||
- private int count;
|
|
||||||
-
|
|
||||||
- public ReferenceList() {
|
|
||||||
- this((E[])EMPTY_LIST);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- public ReferenceList(final E[] referenceArray) {
|
|
||||||
- this.references = referenceArray;
|
|
||||||
- this.referenceToIndex = new Reference2IntOpenHashMap<>(2, 0.8f);
|
|
||||||
- this.referenceToIndex.defaultReturnValue(Integer.MIN_VALUE);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- private ReferenceList(final E[] references, final int count, final Reference2IntOpenHashMap<E> referenceToIndex) {
|
|
||||||
- this.references = references;
|
|
||||||
- this.count = count;
|
|
||||||
- this.referenceToIndex = referenceToIndex;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- public ReferenceList<E> copy() {
|
|
||||||
- return new ReferenceList<>(this.references.clone(), this.count, this.referenceToIndex.clone());
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- public int size() {
|
|
||||||
- return this.count;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- public boolean contains(final E obj) {
|
|
||||||
- return this.referenceToIndex.containsKey(obj);
|
|
||||||
+public class ReferenceList<E> extends ReferenceLists.SynchronizedList<E> {
|
|
||||||
+ public ReferenceList(E[] elements) {
|
|
||||||
+ super(new RefListInner<>(elements));
|
|
||||||
}
|
|
||||||
|
|
||||||
- public boolean remove(final E obj) {
|
|
||||||
- final int index = this.referenceToIndex.removeInt(obj);
|
|
||||||
- if (index == Integer.MIN_VALUE) {
|
|
||||||
- return false;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- // move the object at the end to this index
|
|
||||||
- final int endIndex = --this.count;
|
|
||||||
- final E end = (E)this.references[endIndex];
|
|
||||||
- if (index != endIndex) {
|
|
||||||
- // not empty after this call
|
|
||||||
- this.referenceToIndex.put(end, index); // update index
|
|
||||||
- }
|
|
||||||
- this.references[index] = end;
|
|
||||||
- this.references[endIndex] = null;
|
|
||||||
-
|
|
||||||
- return true;
|
|
||||||
+ public synchronized E[] getRawDataUnchecked() {
|
|
||||||
+ return ((RefListInner<E>) this.list).getRawDataUnchecked();
|
|
||||||
}
|
|
||||||
|
|
||||||
- public boolean add(final E obj) {
|
|
||||||
- final int count = this.count;
|
|
||||||
- final int currIndex = this.referenceToIndex.putIfAbsent(obj, count);
|
|
||||||
-
|
|
||||||
- if (currIndex != Integer.MIN_VALUE) {
|
|
||||||
- return false; // already in this list
|
|
||||||
+ public static class RefListInner<A> extends ReferenceArrayList<A> {
|
|
||||||
+ public RefListInner(A[] elements) {
|
|
||||||
+ super(elements, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
- E[] list = this.references;
|
|
||||||
-
|
|
||||||
- if (list.length == count) {
|
|
||||||
- // resize required
|
|
||||||
- list = this.references = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative
|
|
||||||
+ public A[] getRawDataUnchecked() {
|
|
||||||
+ return this.a;
|
|
||||||
}
|
|
||||||
-
|
|
||||||
- list[count] = obj;
|
|
||||||
- this.count = count + 1;
|
|
||||||
-
|
|
||||||
- return true;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- public E getChecked(final int index) {
|
|
||||||
- if (index < 0 || index >= this.count) {
|
|
||||||
- throw new IndexOutOfBoundsException("Index: " + index + " is out of bounds, size: " + this.count);
|
|
||||||
- }
|
|
||||||
- return this.references[index];
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- public E getUnchecked(final int index) {
|
|
||||||
- return this.references[index];
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- public Object[] getRawData() {
|
|
||||||
- return this.references;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- public E[] getRawDataUnchecked() {
|
|
||||||
- return this.references;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- public void clear() {
|
|
||||||
- this.referenceToIndex.clear();
|
|
||||||
- Arrays.fill(this.references, 0, this.count, null);
|
|
||||||
- this.count = 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- @Override
|
|
||||||
- public Iterator<E> iterator() {
|
|
||||||
- return new Iterator<>() {
|
|
||||||
- private E lastRet;
|
|
||||||
- private int current;
|
|
||||||
-
|
|
||||||
- @Override
|
|
||||||
- public boolean hasNext() {
|
|
||||||
- return this.current < ReferenceList.this.count;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- @Override
|
|
||||||
- public E next() {
|
|
||||||
- if (this.current >= ReferenceList.this.count) {
|
|
||||||
- throw new NoSuchElementException();
|
|
||||||
- }
|
|
||||||
- return this.lastRet = ReferenceList.this.references[this.current++];
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- @Override
|
|
||||||
- public void remove() {
|
|
||||||
- final E lastRet = this.lastRet;
|
|
||||||
-
|
|
||||||
- if (lastRet == null) {
|
|
||||||
- throw new IllegalStateException();
|
|
||||||
- }
|
|
||||||
- this.lastRet = null;
|
|
||||||
-
|
|
||||||
- ReferenceList.this.remove(lastRet);
|
|
||||||
- --this.current;
|
|
||||||
- }
|
|
||||||
- };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+// DivineMC end - Rewrite ReferenceList
|
|
||||||
@@ -0,0 +1,508 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
||||||
|
Date: Wed, 9 Jul 2025 03:37:51 +0300
|
||||||
|
Subject: [PATCH] Optimize Moonrise
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java
|
||||||
|
index 7fed43a1e7bcf35c4d7fd3224837a47fedd59860..6c002ba690a8cc7335276e039f49c4251076cc92 100644
|
||||||
|
--- a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java
|
||||||
|
+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java
|
||||||
|
@@ -1,5 +1,7 @@
|
||||||
|
package ca.spottedleaf.moonrise.common.list;
|
||||||
|
|
||||||
|
+import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||||
|
+import it.unimi.dsi.fastutil.ints.Int2IntMaps;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import java.util.Arrays;
|
||||||
|
@@ -13,7 +15,7 @@ import java.util.NoSuchElementException;
|
||||||
|
*/
|
||||||
|
public final class EntityList implements Iterable<Entity> {
|
||||||
|
|
||||||
|
- private final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f);
|
||||||
|
+ private final Int2IntMap entityToIndex = Int2IntMaps.synchronize(new Int2IntOpenHashMap(2, 0.8f)); // DivineMC - Optimize Moonrise
|
||||||
|
{
|
||||||
|
this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE);
|
||||||
|
}
|
||||||
|
@@ -27,11 +29,11 @@ public final class EntityList implements Iterable<Entity> {
|
||||||
|
return this.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
- public boolean contains(final Entity entity) {
|
||||||
|
+ public synchronized boolean contains(final Entity entity) { // DivineMC - Optimize Moonrise
|
||||||
|
return this.entityToIndex.containsKey(entity.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
- public boolean remove(final Entity entity) {
|
||||||
|
+ public synchronized boolean remove(final Entity entity) { // DivineMC - Optimize Moonrise
|
||||||
|
final int index = this.entityToIndex.remove(entity.getId());
|
||||||
|
if (index == Integer.MIN_VALUE) {
|
||||||
|
return false;
|
||||||
|
@@ -50,7 +52,7 @@ public final class EntityList implements Iterable<Entity> {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
- public boolean add(final Entity entity) {
|
||||||
|
+ public synchronized boolean add(final Entity entity) { // DivineMC - Optimize Moonrise
|
||||||
|
final int count = this.count;
|
||||||
|
final int currIndex = this.entityToIndex.putIfAbsent(entity.getId(), count);
|
||||||
|
|
||||||
|
@@ -82,18 +84,18 @@ public final class EntityList implements Iterable<Entity> {
|
||||||
|
return this.entities[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
- public Entity[] getRawData() {
|
||||||
|
+ public synchronized Entity[] getRawData() { // DivineMC - Optimize Moonrise
|
||||||
|
return this.entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
- public void clear() {
|
||||||
|
+ public synchronized void clear() { // DivineMC - Optimize Moonrise
|
||||||
|
this.entityToIndex.clear();
|
||||||
|
Arrays.fill(this.entities, 0, this.count, null);
|
||||||
|
this.count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
- public Iterator<Entity> iterator() {
|
||||||
|
+ public synchronized Iterator<Entity> iterator() { // DivineMC - Optimize Moonrise
|
||||||
|
return new Iterator<>() {
|
||||||
|
private Entity lastRet;
|
||||||
|
private int current;
|
||||||
|
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java
|
||||||
|
index 2e876b918672e8ef3b5197b7e6b1597247fdeaa1..c93a9d2de61c9aa789c0758de0bdafaa4af2c93f 100644
|
||||||
|
--- a/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java
|
||||||
|
+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java
|
||||||
|
@@ -1,142 +1,26 @@
|
||||||
|
package ca.spottedleaf.moonrise.common.list;
|
||||||
|
|
||||||
|
-import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
|
||||||
|
-import java.util.Arrays;
|
||||||
|
-import java.util.Iterator;
|
||||||
|
-import java.util.NoSuchElementException;
|
||||||
|
+// DivineMC start - Optimize Moonrise
|
||||||
|
+import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
|
||||||
|
+import it.unimi.dsi.fastutil.objects.ReferenceLists;
|
||||||
|
|
||||||
|
-public final class ReferenceList<E> implements Iterable<E> {
|
||||||
|
-
|
||||||
|
- private static final Object[] EMPTY_LIST = new Object[0];
|
||||||
|
-
|
||||||
|
- private final Reference2IntOpenHashMap<E> referenceToIndex;
|
||||||
|
- private E[] references;
|
||||||
|
- private int count;
|
||||||
|
-
|
||||||
|
- public ReferenceList() {
|
||||||
|
- this((E[])EMPTY_LIST);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- public ReferenceList(final E[] referenceArray) {
|
||||||
|
- this.references = referenceArray;
|
||||||
|
- this.referenceToIndex = new Reference2IntOpenHashMap<>(2, 0.8f);
|
||||||
|
- this.referenceToIndex.defaultReturnValue(Integer.MIN_VALUE);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- private ReferenceList(final E[] references, final int count, final Reference2IntOpenHashMap<E> referenceToIndex) {
|
||||||
|
- this.references = references;
|
||||||
|
- this.count = count;
|
||||||
|
- this.referenceToIndex = referenceToIndex;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- public ReferenceList<E> copy() {
|
||||||
|
- return new ReferenceList<>(this.references.clone(), this.count, this.referenceToIndex.clone());
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- public int size() {
|
||||||
|
- return this.count;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- public boolean contains(final E obj) {
|
||||||
|
- return this.referenceToIndex.containsKey(obj);
|
||||||
|
+public class ReferenceList<E> extends ReferenceLists.SynchronizedList<E> {
|
||||||
|
+ public ReferenceList(E[] elements) {
|
||||||
|
+ super(new RefListInner<>(elements));
|
||||||
|
}
|
||||||
|
|
||||||
|
- public boolean remove(final E obj) {
|
||||||
|
- final int index = this.referenceToIndex.removeInt(obj);
|
||||||
|
- if (index == Integer.MIN_VALUE) {
|
||||||
|
- return false;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // move the object at the end to this index
|
||||||
|
- final int endIndex = --this.count;
|
||||||
|
- final E end = (E)this.references[endIndex];
|
||||||
|
- if (index != endIndex) {
|
||||||
|
- // not empty after this call
|
||||||
|
- this.referenceToIndex.put(end, index); // update index
|
||||||
|
- }
|
||||||
|
- this.references[index] = end;
|
||||||
|
- this.references[endIndex] = null;
|
||||||
|
-
|
||||||
|
- return true;
|
||||||
|
+ public synchronized E[] getRawDataUnchecked() {
|
||||||
|
+ return ((RefListInner<E>) this.list).getRawDataUnchecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
- public boolean add(final E obj) {
|
||||||
|
- final int count = this.count;
|
||||||
|
- final int currIndex = this.referenceToIndex.putIfAbsent(obj, count);
|
||||||
|
-
|
||||||
|
- if (currIndex != Integer.MIN_VALUE) {
|
||||||
|
- return false; // already in this list
|
||||||
|
+ public static class RefListInner<A> extends ReferenceArrayList<A> {
|
||||||
|
+ public RefListInner(A[] elements) {
|
||||||
|
+ super(elements, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
- E[] list = this.references;
|
||||||
|
-
|
||||||
|
- if (list.length == count) {
|
||||||
|
- // resize required
|
||||||
|
- list = this.references = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative
|
||||||
|
+ public A[] getRawDataUnchecked() {
|
||||||
|
+ return this.a;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- list[count] = obj;
|
||||||
|
- this.count = count + 1;
|
||||||
|
-
|
||||||
|
- return true;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- public E getChecked(final int index) {
|
||||||
|
- if (index < 0 || index >= this.count) {
|
||||||
|
- throw new IndexOutOfBoundsException("Index: " + index + " is out of bounds, size: " + this.count);
|
||||||
|
- }
|
||||||
|
- return this.references[index];
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- public E getUnchecked(final int index) {
|
||||||
|
- return this.references[index];
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- public Object[] getRawData() {
|
||||||
|
- return this.references;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- public E[] getRawDataUnchecked() {
|
||||||
|
- return this.references;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- public void clear() {
|
||||||
|
- this.referenceToIndex.clear();
|
||||||
|
- Arrays.fill(this.references, 0, this.count, null);
|
||||||
|
- this.count = 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- @Override
|
||||||
|
- public Iterator<E> iterator() {
|
||||||
|
- return new Iterator<>() {
|
||||||
|
- private E lastRet;
|
||||||
|
- private int current;
|
||||||
|
-
|
||||||
|
- @Override
|
||||||
|
- public boolean hasNext() {
|
||||||
|
- return this.current < ReferenceList.this.count;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- @Override
|
||||||
|
- public E next() {
|
||||||
|
- if (this.current >= ReferenceList.this.count) {
|
||||||
|
- throw new NoSuchElementException();
|
||||||
|
- }
|
||||||
|
- return this.lastRet = ReferenceList.this.references[this.current++];
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- @Override
|
||||||
|
- public void remove() {
|
||||||
|
- final E lastRet = this.lastRet;
|
||||||
|
-
|
||||||
|
- if (lastRet == null) {
|
||||||
|
- throw new IllegalStateException();
|
||||||
|
- }
|
||||||
|
- this.lastRet = null;
|
||||||
|
-
|
||||||
|
- ReferenceList.this.remove(lastRet);
|
||||||
|
- --this.current;
|
||||||
|
- }
|
||||||
|
- };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+// DivineMC end - Optimize Moonrise
|
||||||
|
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java
|
||||||
|
index 2bae9949ef325d0001aa638150fbbdf968367e75..f946e625dcfec5c6ee9bf90bb79ac1c2f84ec048 100644
|
||||||
|
--- a/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java
|
||||||
|
+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java
|
||||||
|
@@ -1,11 +1,13 @@
|
||||||
|
package ca.spottedleaf.moonrise.common.list;
|
||||||
|
|
||||||
|
+import it.unimi.dsi.fastutil.shorts.Short2ShortMap;
|
||||||
|
+import it.unimi.dsi.fastutil.shorts.Short2ShortMaps;
|
||||||
|
import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public final class ShortList {
|
||||||
|
|
||||||
|
- private final Short2ShortOpenHashMap map = new Short2ShortOpenHashMap();
|
||||||
|
+ private final Short2ShortMap map = Short2ShortMaps.synchronize(new Short2ShortOpenHashMap()); // DivineMC - Optimize Moonrise
|
||||||
|
{
|
||||||
|
this.map.defaultReturnValue(Short.MIN_VALUE);
|
||||||
|
}
|
||||||
|
@@ -13,13 +15,13 @@ public final class ShortList {
|
||||||
|
private static final short[] EMPTY_LIST = new short[0];
|
||||||
|
|
||||||
|
private short[] byIndex = EMPTY_LIST;
|
||||||
|
- private short count;
|
||||||
|
+ private volatile short count; // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
- return (int)this.count;
|
||||||
|
+ return this.count; // DivineMC - Optimize Moonrise
|
||||||
|
}
|
||||||
|
|
||||||
|
- public short getRaw(final int index) {
|
||||||
|
+ public synchronized short getRaw(final int index) { // DivineMC - Optimize Moonrise
|
||||||
|
return this.byIndex[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -30,8 +32,8 @@ public final class ShortList {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- public boolean add(final short value) {
|
||||||
|
- final int count = (int)this.count;
|
||||||
|
+ public synchronized boolean add(final short value) { // DivineMC - Optimize Moonrise
|
||||||
|
+ final int count = this.count; // DivineMC - Optimize Moonrise
|
||||||
|
final short currIndex = this.map.putIfAbsent(value, (short)count);
|
||||||
|
|
||||||
|
if (currIndex != Short.MIN_VALUE) {
|
||||||
|
@@ -51,7 +53,7 @@ public final class ShortList {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
- public boolean remove(final short value) {
|
||||||
|
+ public synchronized boolean remove(final short value) { // DivineMC - Optimize Moonrise
|
||||||
|
final short index = this.map.remove(value);
|
||||||
|
if (index == Short.MIN_VALUE) {
|
||||||
|
return false;
|
||||||
|
@@ -70,7 +72,7 @@ public final class ShortList {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
- public void clear() {
|
||||||
|
+ public synchronized void clear() { // DivineMC - Optimize Moonrise
|
||||||
|
this.count = (short)0;
|
||||||
|
this.map.clear();
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed26WayDistancePropagator3D.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed26WayDistancePropagator3D.java
|
||||||
|
index 460e27ab0506c83a28934800ee74ee886d4b025e..59e80748de2b0b35ecf25739e1876ebcbce7eca5 100644
|
||||||
|
--- a/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed26WayDistancePropagator3D.java
|
||||||
|
+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed26WayDistancePropagator3D.java
|
||||||
|
@@ -15,7 +15,7 @@ public final class Delayed26WayDistancePropagator3D {
|
||||||
|
|
||||||
|
// Generally updates to positions are made close to other updates, so we link to decrease cache misses when
|
||||||
|
// propagating updates
|
||||||
|
- protected final LongLinkedOpenHashSet updatedSources = new LongLinkedOpenHashSet();
|
||||||
|
+ protected final it.unimi.dsi.fastutil.longs.LongSet updatedSources = it.unimi.dsi.fastutil.longs.LongSets.synchronize(new LongLinkedOpenHashSet()); // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public static interface LevelChangeCallback {
|
||||||
|
@@ -94,29 +94,29 @@ public final class Delayed26WayDistancePropagator3D {
|
||||||
|
|
||||||
|
protected final void addToIncreaseWorkQueue(final long coordinate, final byte level) {
|
||||||
|
final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[level];
|
||||||
|
- queue.queuedCoordinates.enqueue(coordinate);
|
||||||
|
- queue.queuedLevels.enqueue(level);
|
||||||
|
+ queue.queuedCoordinates.add(coordinate); // DivineMC - Optimize Moonrise
|
||||||
|
+ queue.queuedLevels.add(level); // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
this.levelIncreaseWorkQueueBitset |= (1L << level);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void addToIncreaseWorkQueue(final long coordinate, final byte index, final byte level) {
|
||||||
|
final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[index];
|
||||||
|
- queue.queuedCoordinates.enqueue(coordinate);
|
||||||
|
- queue.queuedLevels.enqueue(level);
|
||||||
|
+ queue.queuedCoordinates.add(coordinate); // DivineMC - Optimize Moonrise
|
||||||
|
+ queue.queuedLevels.add(level); // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
this.levelIncreaseWorkQueueBitset |= (1L << index);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void addToRemoveWorkQueue(final long coordinate, final byte level) {
|
||||||
|
final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelRemoveWorkQueues[level];
|
||||||
|
- queue.queuedCoordinates.enqueue(coordinate);
|
||||||
|
- queue.queuedLevels.enqueue(level);
|
||||||
|
+ queue.queuedCoordinates.add(coordinate); // DivineMC - Optimize Moonrise
|
||||||
|
+ queue.queuedLevels.add(level); // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
this.levelRemoveWorkQueueBitset |= (1L << level);
|
||||||
|
}
|
||||||
|
|
||||||
|
- public boolean propagateUpdates() {
|
||||||
|
+ public synchronized boolean propagateUpdates() { // DivineMC - Optimize Moonrise
|
||||||
|
if (this.updatedSources.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@@ -157,15 +157,15 @@ public final class Delayed26WayDistancePropagator3D {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- protected void propagateIncreases() {
|
||||||
|
+ protected synchronized void propagateIncreases() { // DivineMC - Optimize Moonrise
|
||||||
|
for (int queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelIncreaseWorkQueueBitset);
|
||||||
|
this.levelIncreaseWorkQueueBitset != 0L;
|
||||||
|
this.levelIncreaseWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelIncreaseWorkQueueBitset)) {
|
||||||
|
|
||||||
|
final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[queueIndex];
|
||||||
|
while (!queue.queuedLevels.isEmpty()) {
|
||||||
|
- final long coordinate = queue.queuedCoordinates.removeFirstLong();
|
||||||
|
- byte level = queue.queuedLevels.removeFirstByte();
|
||||||
|
+ final long coordinate = queue.queuedCoordinates.removeFirst(); // DivineMC - Optimize Moonrise
|
||||||
|
+ byte level = queue.queuedLevels.removeFirst(); // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
final boolean neighbourCheck = level < 0;
|
||||||
|
|
||||||
|
@@ -226,15 +226,15 @@ public final class Delayed26WayDistancePropagator3D {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- protected void propagateDecreases() {
|
||||||
|
+ protected synchronized void propagateDecreases() { // DivineMC - Optimize Moonrise
|
||||||
|
for (int queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelRemoveWorkQueueBitset);
|
||||||
|
this.levelRemoveWorkQueueBitset != 0L;
|
||||||
|
this.levelRemoveWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelRemoveWorkQueueBitset)) {
|
||||||
|
|
||||||
|
final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelRemoveWorkQueues[queueIndex];
|
||||||
|
while (!queue.queuedLevels.isEmpty()) {
|
||||||
|
- final long coordinate = queue.queuedCoordinates.removeFirstLong();
|
||||||
|
- final byte level = queue.queuedLevels.removeFirstByte();
|
||||||
|
+ final long coordinate = queue.queuedCoordinates.removeFirst(); // DivineMC - Optimize Moonrise
|
||||||
|
+ final byte level = queue.queuedLevels.removeFirst(); // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
final byte currentLevel = this.levels.removeIfGreaterOrEqual(coordinate, level);
|
||||||
|
if (currentLevel == 0) {
|
||||||
|
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed8WayDistancePropagator2D.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed8WayDistancePropagator2D.java
|
||||||
|
index ab2fa1563d5e32a5313dfcc1da411cab45fb5ca0..f568fcf85667cd3fe53f59e08451096de5fa3492 100644
|
||||||
|
--- a/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed8WayDistancePropagator2D.java
|
||||||
|
+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed8WayDistancePropagator2D.java
|
||||||
|
@@ -356,24 +356,24 @@ public final class Delayed8WayDistancePropagator2D {
|
||||||
|
|
||||||
|
protected final void addToIncreaseWorkQueue(final long coordinate, final byte level) {
|
||||||
|
final WorkQueue queue = this.levelIncreaseWorkQueues[level];
|
||||||
|
- queue.queuedCoordinates.enqueue(coordinate);
|
||||||
|
- queue.queuedLevels.enqueue(level);
|
||||||
|
+ queue.queuedCoordinates.add(coordinate); // DivineMC - Optimize Moonrise
|
||||||
|
+ queue.queuedLevels.add(level); // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
this.levelIncreaseWorkQueueBitset |= (1L << level);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void addToIncreaseWorkQueue(final long coordinate, final byte index, final byte level) {
|
||||||
|
final WorkQueue queue = this.levelIncreaseWorkQueues[index];
|
||||||
|
- queue.queuedCoordinates.enqueue(coordinate);
|
||||||
|
- queue.queuedLevels.enqueue(level);
|
||||||
|
+ queue.queuedCoordinates.add(coordinate); // DivineMC - Optimize Moonrise
|
||||||
|
+ queue.queuedLevels.add(level); // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
this.levelIncreaseWorkQueueBitset |= (1L << index);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void addToRemoveWorkQueue(final long coordinate, final byte level) {
|
||||||
|
final WorkQueue queue = this.levelRemoveWorkQueues[level];
|
||||||
|
- queue.queuedCoordinates.enqueue(coordinate);
|
||||||
|
- queue.queuedLevels.enqueue(level);
|
||||||
|
+ queue.queuedCoordinates.add(coordinate); // DivineMC - Optimize Moonrise
|
||||||
|
+ queue.queuedLevels.add(level); // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
this.levelRemoveWorkQueueBitset |= (1L << level);
|
||||||
|
}
|
||||||
|
@@ -426,8 +426,8 @@ public final class Delayed8WayDistancePropagator2D {
|
||||||
|
|
||||||
|
final WorkQueue queue = this.levelIncreaseWorkQueues[queueIndex];
|
||||||
|
while (!queue.queuedLevels.isEmpty()) {
|
||||||
|
- final long coordinate = queue.queuedCoordinates.removeFirstLong();
|
||||||
|
- byte level = queue.queuedLevels.removeFirstByte();
|
||||||
|
+ final long coordinate = queue.queuedCoordinates.removeFirst(); // DivineMC - Optimize Moonrise
|
||||||
|
+ byte level = queue.queuedLevels.removeFirst(); // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
final boolean neighbourCheck = level < 0;
|
||||||
|
|
||||||
|
@@ -492,8 +492,8 @@ public final class Delayed8WayDistancePropagator2D {
|
||||||
|
|
||||||
|
final WorkQueue queue = this.levelRemoveWorkQueues[queueIndex];
|
||||||
|
while (!queue.queuedLevels.isEmpty()) {
|
||||||
|
- final long coordinate = queue.queuedCoordinates.removeFirstLong();
|
||||||
|
- final byte level = queue.queuedLevels.removeFirstByte();
|
||||||
|
+ final long coordinate = queue.queuedCoordinates.removeFirst(); // DivineMC - Optimize Moonrise
|
||||||
|
+ final byte level = queue.queuedLevels.removeFirst(); // DivineMC - Optimize Moonrise
|
||||||
|
|
||||||
|
final byte currentLevel = this.levels.removeIfGreaterOrEqual(coordinate, level);
|
||||||
|
if (currentLevel == 0) {
|
||||||
|
@@ -561,7 +561,7 @@ public final class Delayed8WayDistancePropagator2D {
|
||||||
|
}
|
||||||
|
|
||||||
|
// copied from superclass
|
||||||
|
- private int find(final long k) {
|
||||||
|
+ private synchronized int find(final long k) { // DivineMC - Optimize Moonrise
|
||||||
|
if (k == 0L) {
|
||||||
|
return this.containsNullKey ? this.n : -(this.n + 1);
|
||||||
|
} else {
|
||||||
|
@@ -585,7 +585,7 @@ public final class Delayed8WayDistancePropagator2D {
|
||||||
|
}
|
||||||
|
|
||||||
|
// copied from superclass
|
||||||
|
- private void insert(final int pos, final long k, final byte v) {
|
||||||
|
+ private synchronized void insert(final int pos, final long k, final byte v) { // DivineMC - Optimize Moonrise
|
||||||
|
if (pos == this.n) {
|
||||||
|
this.containsNullKey = true;
|
||||||
|
}
|
||||||
|
@@ -598,7 +598,7 @@ public final class Delayed8WayDistancePropagator2D {
|
||||||
|
}
|
||||||
|
|
||||||
|
// copied from superclass
|
||||||
|
- public byte putIfGreater(final long key, final byte value) {
|
||||||
|
+ public synchronized byte putIfGreater(final long key, final byte value) { // DivineMC - Optimize Moonrise
|
||||||
|
final int pos = this.find(key);
|
||||||
|
if (pos < 0) {
|
||||||
|
if (this.defRetValue < value) {
|
||||||
|
@@ -616,7 +616,7 @@ public final class Delayed8WayDistancePropagator2D {
|
||||||
|
}
|
||||||
|
|
||||||
|
// copied from superclass
|
||||||
|
- private void removeEntry(final int pos) {
|
||||||
|
+ private synchronized void removeEntry(final int pos) { // DivineMC - Optimize Moonrise
|
||||||
|
--this.size;
|
||||||
|
this.shiftKeys(pos);
|
||||||
|
if (this.n > this.minN && this.size < this.maxFill / 4 && this.n > 16) {
|
||||||
|
@@ -625,7 +625,7 @@ public final class Delayed8WayDistancePropagator2D {
|
||||||
|
}
|
||||||
|
|
||||||
|
// copied from superclass
|
||||||
|
- private void removeNullEntry() {
|
||||||
|
+ private synchronized void removeNullEntry() { // DivineMC - Optimize Moonrise
|
||||||
|
this.containsNullKey = false;
|
||||||
|
--this.size;
|
||||||
|
if (this.n > this.minN && this.size < this.maxFill / 4 && this.n > 16) {
|
||||||
|
@@ -634,7 +634,7 @@ public final class Delayed8WayDistancePropagator2D {
|
||||||
|
}
|
||||||
|
|
||||||
|
// copied from superclass
|
||||||
|
- public byte removeIfGreaterOrEqual(final long key, final byte value) {
|
||||||
|
+ public synchronized byte removeIfGreaterOrEqual(final long key, final byte value) { // DivineMC - Optimize Moonrise
|
||||||
|
if (key == 0L) {
|
||||||
|
if (!this.containsNullKey) {
|
||||||
|
return this.defRetValue;
|
||||||
|
@@ -679,8 +679,8 @@ public final class Delayed8WayDistancePropagator2D {
|
||||||
|
|
||||||
|
protected static final class WorkQueue {
|
||||||
|
|
||||||
|
- public final NoResizeLongArrayFIFODeque queuedCoordinates = new NoResizeLongArrayFIFODeque();
|
||||||
|
- public final NoResizeByteArrayFIFODeque queuedLevels = new NoResizeByteArrayFIFODeque();
|
||||||
|
+ public final java.util.concurrent.ConcurrentLinkedDeque<Long> queuedCoordinates = new java.util.concurrent.ConcurrentLinkedDeque<>();
|
||||||
|
+ public final java.util.concurrent.ConcurrentLinkedDeque<Byte> queuedLevels = new java.util.concurrent.ConcurrentLinkedDeque<>();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user