mirror of
https://github.com/BX-Team/DivineMC.git
synced 2025-12-19 14:59:25 +00:00
505 lines
30 KiB
Diff
505 lines
30 KiB
Diff
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/level/entity/EntityLookup.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java
|
|
index 2d24d03bbdb5ee0d862cbfff2219f58afffafe12..b4c55b8fee8dbab278e096580702a05282da2d51 100644
|
|
--- a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java
|
|
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java
|
|
@@ -93,8 +93,14 @@ public abstract class EntityLookup implements LevelEntityGetter<Entity> {
|
|
if (entity == null) {
|
|
return null;
|
|
}
|
|
- final Visibility visibility = EntityLookup.getEntityStatus(entity);
|
|
- return visibility.isAccessible() ? entity : null;
|
|
+ // DivineMC start - Optimize Moonrise
|
|
+ final FullChunkStatus entityStatus = ((ChunkSystemEntity) entity).moonrise$getChunkStatus();
|
|
+ return switch (entityStatus) {
|
|
+ case INACCESSIBLE -> null;
|
|
+ case FULL, BLOCK_TICKING, ENTITY_TICKING -> entity;
|
|
+ case null -> null;
|
|
+ };
|
|
+ // DivineMC end - Optimize Moonrise
|
|
}
|
|
|
|
@Override
|
|
@@ -398,7 +404,14 @@ public abstract class EntityLookup implements LevelEntityGetter<Entity> {
|
|
return Visibility.TICKING;
|
|
}
|
|
final FullChunkStatus entityStatus = ((ChunkSystemEntity)entity).moonrise$getChunkStatus();
|
|
- return Visibility.fromFullChunkStatus(entityStatus == null ? FullChunkStatus.INACCESSIBLE : entityStatus);
|
|
+ // DivineMC start - Optimize Moonrise
|
|
+ return switch (entityStatus) {
|
|
+ case INACCESSIBLE -> Visibility.HIDDEN;
|
|
+ case FULL, BLOCK_TICKING -> Visibility.TRACKED;
|
|
+ case ENTITY_TICKING -> Visibility.TICKING;
|
|
+ case null -> Visibility.HIDDEN;
|
|
+ };
|
|
+ // DivineMC end - Optimize Moonrise
|
|
}
|
|
|
|
protected boolean addEntity(final Entity entity, final boolean fromDisk, final boolean event) {
|
|
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
|
index 18822bed7986348bbbed1712db7dac65884d39a9..906c0019cae2529962d1221939ce276f2c28dae9 100644
|
|
--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
|
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
|
@@ -75,37 +75,49 @@ public final class ChunkHolderManager {
|
|
private static final long NO_TIMEOUT_MARKER = Long.MIN_VALUE;
|
|
public final ReentrantAreaLock ticketLockArea;
|
|
|
|
- private final ConcurrentLong2ReferenceChainedHashTable<TicketSet> tickets = new ConcurrentLong2ReferenceChainedHashTable<>();
|
|
- private final ConcurrentLong2ReferenceChainedHashTable<Long2IntOpenHashMap> sectionToChunkToExpireCount = new ConcurrentLong2ReferenceChainedHashTable<>();
|
|
+ private final ConcurrentLong2ReferenceChainedHashTable<TicketSet> tickets = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(20, 0.9F);
|
|
+ private final ConcurrentLong2ReferenceChainedHashTable<Long2IntOpenHashMap> sectionToChunkToExpireCount = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(20, 0.9F);
|
|
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
|
|
|
|
// mapping of counter id -> (mapping of pos->count)
|
|
private final ConcurrentLong2ReferenceChainedHashTable<ConcurrentLong2LongChainedHashTable> ticketCounters = new ConcurrentLong2ReferenceChainedHashTable<>();
|
|
@@ -229,26 +241,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) {
|
|
@@ -262,10 +277,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 boolean emergency) {
|
|
@@ -469,8 +485,8 @@ public final class ChunkHolderManager {
|
|
final Long2ObjectOpenHashMap<Collection<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,
|
|
@@ -567,7 +583,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);
|
|
}
|
|
@@ -763,8 +779,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,
|
|
@@ -818,8 +834,8 @@ public final class ChunkHolderManager {
|
|
|
|
Ticket[] removedList = new Ticket[4];
|
|
|
|
- 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
|
|
@@ -1132,18 +1148,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));
|
|
}
|
|
@@ -1307,6 +1323,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
|
|
}
|
|
@@ -1470,8 +1507,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) {
|
|
@@ -1483,7 +1522,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 9a9a599ef178f851ee5c783631a724013a693586..7f8e7d0aac516489dbbc10da68161f3ff3b2908d 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) {}
|
|
@@ -1168,6 +1178,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);
|
|
@@ -1192,6 +1203,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
|
|
@@ -1326,7 +1350,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) -> {
|
|
@@ -1361,7 +1385,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/chunk_system/util/ParallelSearchRadiusIteration.java b/ca/spottedleaf/moonrise/patches/chunk_system/util/ParallelSearchRadiusIteration.java
|
|
index 93fd23027c00cef76562098306737272fda1350a..40856bf4148ce59cf34a470df9fc7e64088b793a 100644
|
|
--- a/ca/spottedleaf/moonrise/patches/chunk_system/util/ParallelSearchRadiusIteration.java
|
|
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/util/ParallelSearchRadiusIteration.java
|
|
@@ -23,7 +23,7 @@ public final class ParallelSearchRadiusIteration {
|
|
}
|
|
|
|
public static long[] getSearchIteration(final int radius) {
|
|
- return SEARCH_RADIUS_ITERATION_LIST[radius];
|
|
+ return SEARCH_RADIUS_ITERATION_LIST[Math.min(SEARCH_RADIUS_ITERATION_LIST.length - 1, radius)]; // DivineMC - Optimize Moonrise - Fix #130
|
|
}
|
|
|
|
private static class CustomLongArray extends LongArrayList {
|
|
diff --git a/ca/spottedleaf/moonrise/patches/starlight/light/SWMRNibbleArray.java b/ca/spottedleaf/moonrise/patches/starlight/light/SWMRNibbleArray.java
|
|
index 5c7b3804cdbcb0a873a0d195325c2658760a8914..4bb64bc5a31951a83d29d0c88919b1fa96e994a3 100644
|
|
--- a/ca/spottedleaf/moonrise/patches/starlight/light/SWMRNibbleArray.java
|
|
+++ b/ca/spottedleaf/moonrise/patches/starlight/light/SWMRNibbleArray.java
|
|
@@ -326,7 +326,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 d03d075d5c56b7d2beb5f0aafecbb69f5b3bbf5b..ce3b8f4161dde3e2758c5d33445da15027fb0f33 100644
|
|
--- a/net/minecraft/server/level/DistanceManager.java
|
|
+++ b/net/minecraft/server/level/DistanceManager.java
|
|
@@ -128,15 +128,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 dda53860397ee52f64209a8d08a7707cfa2f7592..8acdce5a4f5546d0fb5907cfc45731c40372e3ed 100644
|
|
--- a/net/minecraft/server/level/ServerChunkCache.java
|
|
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
|
@@ -461,8 +461,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 ba496e78740218a176d8e3117a21cbfc5173cfef..14790f65b00ede0c063c567f524674270ca58b5c 100644
|
|
--- a/net/minecraft/server/level/ServerLevel.java
|
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
|
@@ -186,6 +186,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
|
|
final EntityTickList entityTickList = new EntityTickList(this); // DivineMC - Parallel world ticking
|
|
private final ServerWaypointManager waypointManager;
|
|
// Paper - rewrite chunk system
|
|
@@ -733,6 +734,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"),
|
|
@@ -912,8 +914,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
|
|
}
|
|
|
|
@@ -2668,16 +2669,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
|
|
}
|
|
|