9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-19 15:09:25 +00:00
Files
Leaf/leaf-server/minecraft-patches/features/0218-Rework-ChunkHolderManager.patch
2025-04-18 04:38:18 -04:00

134 lines
6.2 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Taiyou06 <kaandindar21@gmail.com>
Date: Thu, 27 Feb 2025 23:39:32 +0100
Subject: [PATCH] Rework ChunkHolderManager
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
index ea4010df54dbd17cdae22d671ea1e4bd7b685b3e..921ac2a1d381268060b9df07c3b2958737e3d14a 100644
--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
@@ -821,24 +821,21 @@ public final class ChunkHolderManager {
final int sectionShift = ((ChunkSystemServerLevel)this.world).moonrise$getRegionChunkShift();
- final Predicate<Ticket> expireNow = (final Ticket ticket) -> {
- long removeDelay = ((ChunkSystemTicket<?>)(Object)ticket).moonrise$getRemoveDelay();
- if (removeDelay == NO_TIMEOUT_MARKER) {
- return false;
- }
- --removeDelay;
- ((ChunkSystemTicket<?>)(Object)ticket).moonrise$setRemoveDelay(removeDelay);
- return removeDelay <= 0L;
- };
+ // Leaf start - Rework ChunkHolderManager
+ // Collect sections to process first to avoid concurrent modification issues
+ List<Long> sectionKeys = new ArrayList<>();
for (final PrimitiveIterator.OfLong iterator = this.sectionToChunkToExpireCount.keyIterator(); iterator.hasNext();) {
- final long sectionKey = iterator.nextLong();
+ sectionKeys.add(iterator.nextLong());
+ }
+ for (final Long sectionKey : sectionKeys) {
+ // Skip if section was removed concurrently
if (!this.sectionToChunkToExpireCount.containsKey(sectionKey)) {
- // removed concurrently
continue;
}
+ // Acquire lock for this section only
final ReentrantAreaLock.Node ticketLock = this.ticketLockArea.lock(
CoordinateUtils.getChunkX(sectionKey) << sectionShift,
CoordinateUtils.getChunkZ(sectionKey) << sectionShift
@@ -846,11 +843,15 @@ public final class ChunkHolderManager {
try {
final Long2IntOpenHashMap chunkToExpireCount = this.sectionToChunkToExpireCount.get(sectionKey);
- if (chunkToExpireCount == null) {
- // lost to some race
+ if (chunkToExpireCount == null || chunkToExpireCount.isEmpty()) {
+ // Section was removed or is empty, clean up
+ if (chunkToExpireCount != null && chunkToExpireCount.isEmpty()) {
+ this.sectionToChunkToExpireCount.remove(sectionKey);
+ }
continue;
}
+ // Process each chunk in this section
for (final Iterator<Long2IntMap.Entry> iterator1 = chunkToExpireCount.long2IntEntrySet().fastIterator(); iterator1.hasNext();) {
final Long2IntMap.Entry entry = iterator1.next();
@@ -858,33 +859,50 @@ public final class ChunkHolderManager {
final int expireCount = entry.getIntValue();
final SortedArraySet<Ticket> tickets = this.tickets.get(chunkKey);
+ if (tickets == null || tickets.isEmpty()) {
+ iterator1.remove();
+ continue;
+ }
+
final int levelBefore = getTicketLevelAt(tickets);
+ int expiredCount = 0;
- final int sizeBefore = tickets.size();
- tickets.removeIf(expireNow);
- final int sizeAfter = tickets.size();
- final int levelAfter = getTicketLevelAt(tickets);
+ // More efficient ticket processing - avoids creating a new predicate each time
+ for (Iterator<Ticket> ticketIterator = tickets.iterator(); ticketIterator.hasNext(); ) {
+ Ticket ticket = ticketIterator.next();
+ long removeDelay = ((ChunkSystemTicket<?>) (Object) ticket).moonrise$getRemoveDelay();
+
+ if (removeDelay == NO_TIMEOUT_MARKER) {
+ continue;
+ }
+
+ --removeDelay;
+ if (removeDelay <= 0) {
+ ticketIterator.remove();
+ expiredCount++;
+ } else {
+ ((ChunkSystemTicket<?>) (Object) ticket).moonrise$setRemoveDelay(removeDelay);
+ }
+ }
if (tickets.isEmpty()) {
this.tickets.remove(chunkKey);
}
+ final int levelAfter = getTicketLevelAt(tickets);
if (levelBefore != levelAfter) {
this.updateTicketLevel(chunkKey, levelAfter);
}
- final int newExpireCount = expireCount - (sizeBefore - sizeAfter);
-
- if (newExpireCount == expireCount) {
- continue;
- }
-
- if (newExpireCount != 0) {
- entry.setValue(newExpireCount);
- } else {
+ // Update expire count
+ final int newExpireCount = expireCount - expiredCount;
+ if (newExpireCount <= 0) {
iterator1.remove();
+ } else if (newExpireCount != expireCount) {
+ entry.setValue(newExpireCount);
}
}
+ // Remove empty sections
if (chunkToExpireCount.isEmpty()) {
this.sectionToChunkToExpireCount.remove(sectionKey);
}
@@ -892,6 +910,7 @@ public final class ChunkHolderManager {
this.ticketLockArea.unlock(ticketLock);
}
}
+ // Leaf end - Rework ChunkHolderManager
this.processTicketUpdates();
}