mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-26 18:39:23 +00:00
* a lot of cleanup and new chunk changes * perf: Head Node Hit Optimization * part 1: reworked-reworked ChunkHolderManager * part 2: speeeeeeeeeeeeeeeeeeeeeeeeeeed * Optimise MobEffectUtil#getDigSpeedAmplification * optimize chunk unloads and cleanup a bit * fix 🐝 * rewritten async target finding * extend the custom map usage --------- Co-authored-by: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
152 lines
7.2 KiB
Diff
152 lines
7.2 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Taiyou06 <kaandindar21@gmail.com>
|
|
Date: Mon, 14 Apr 2025 03:02:42 +0200
|
|
Subject: [PATCH] Reworked ChunkHolderManager
|
|
|
|
|
|
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
|
index a1f328a5c4ccc030c99762a68008ab1ecebdc06e..3de8d0fb485e55f3fc38a65c251f109335595468 100644
|
|
--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
|
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
|
@@ -349,12 +349,13 @@ public final class ChunkHolderManager {
|
|
@Override
|
|
protected void processLevelUpdates(final Long2ByteLinkedOpenHashMap updates) {
|
|
// first the necessary chunkholders must be created, so just update the ticket levels
|
|
+ final LeafConcurrentLong2ReferenceChainedHashTable<NewChunkHolder> holderMap = ChunkHolderManager.this.chunkHolders;
|
|
for (final Iterator<Long2ByteMap.Entry> iterator = updates.long2ByteEntrySet().fastIterator(); iterator.hasNext();) {
|
|
final Long2ByteMap.Entry entry = iterator.next();
|
|
final long key = entry.getLongKey();
|
|
final int newLevel = convertBetweenTicketLevels((int)entry.getByteValue());
|
|
|
|
- NewChunkHolder current = ChunkHolderManager.this.chunkHolders.get(key);
|
|
+ NewChunkHolder current = holderMap.get(key);
|
|
if (current == null && newLevel > MAX_TICKET_LEVEL) {
|
|
// not loaded and it shouldn't be loaded!
|
|
iterator.remove();
|
|
@@ -371,7 +372,7 @@ public final class ChunkHolderManager {
|
|
if (current == null) {
|
|
// must create
|
|
current = ChunkHolderManager.this.createChunkHolder(key);
|
|
- ChunkHolderManager.this.chunkHolders.put(key, current);
|
|
+ holderMap.put(key, current);
|
|
current.updateTicketLevel(newLevel);
|
|
} else {
|
|
current.updateTicketLevel(newLevel);
|
|
@@ -737,20 +738,23 @@ 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;
|
|
+ final long nextDelay = removeDelay - 1;
|
|
+ ((ChunkSystemTicket<?>)(Object)ticket).moonrise$setRemoveDelay(nextDelay);
|
|
+ return nextDelay <= 0L;
|
|
};
|
|
|
|
for (final PrimitiveIterator.OfLong iterator = this.sectionToChunkToExpireCount.keyIterator(); iterator.hasNext();) {
|
|
final long sectionKey = iterator.nextLong();
|
|
|
|
if (!this.sectionToChunkToExpireCount.containsKey(sectionKey)) {
|
|
+
|
|
// removed concurrently
|
|
continue;
|
|
}
|
|
@@ -773,37 +777,62 @@ public final class ChunkHolderManager {
|
|
final long chunkKey = entry.getLongKey();
|
|
final int expireCount = entry.getIntValue();
|
|
|
|
+
|
|
final SortedArraySet<Ticket<?>> tickets = this.tickets.get(chunkKey);
|
|
- final int levelBefore = getTicketLevelAt(tickets);
|
|
+ if (tickets == null) {
|
|
+ iterator1.remove();
|
|
+ continue;
|
|
+ }
|
|
|
|
+ final int levelBefore;
|
|
+ final Ticket<?> firstBefore;
|
|
final int sizeBefore = tickets.size();
|
|
- tickets.removeIf(expireNow);
|
|
- final int sizeAfter = tickets.size();
|
|
- final int levelAfter = getTicketLevelAt(tickets);
|
|
|
|
- if (tickets.isEmpty()) {
|
|
- this.tickets.remove(chunkKey);
|
|
- }
|
|
- if (levelBefore != levelAfter) {
|
|
- this.updateTicketLevel(chunkKey, levelAfter);
|
|
+ if (!tickets.isEmpty()) {
|
|
+ firstBefore = tickets.first();
|
|
+ levelBefore = firstBefore.getTicketLevel();
|
|
+ } else {
|
|
+ firstBefore = null;
|
|
+ levelBefore = MAX_TICKET_LEVEL + 1;
|
|
}
|
|
|
|
- final int newExpireCount = expireCount - (sizeBefore - sizeAfter);
|
|
+ final boolean changed = tickets.removeIf(expireNow);
|
|
|
|
- if (newExpireCount == expireCount) {
|
|
- continue;
|
|
- }
|
|
+ if (changed) {
|
|
+ final int sizeAfter = tickets.size();
|
|
+ final int levelAfter;
|
|
+ boolean levelMightHaveChanged = true;
|
|
|
|
- if (newExpireCount != 0) {
|
|
- entry.setValue(newExpireCount);
|
|
- } else {
|
|
- iterator1.remove();
|
|
+ if (tickets.isEmpty()) {
|
|
+ levelAfter = MAX_TICKET_LEVEL + 1;
|
|
+ this.tickets.remove(chunkKey);
|
|
+ } else {
|
|
+ final Ticket<?> firstAfter = tickets.first();
|
|
+ if (firstBefore == firstAfter) {
|
|
+ levelMightHaveChanged = false;
|
|
+ levelAfter = levelBefore;
|
|
+ } else {
|
|
+ levelAfter = firstAfter.getTicketLevel();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (levelMightHaveChanged && levelBefore != levelAfter) {
|
|
+ this.updateTicketLevel(chunkKey, levelAfter);
|
|
+ }
|
|
+
|
|
+ final int removedCount = sizeBefore - sizeAfter;
|
|
+ if (removedCount > 0) {
|
|
+ final int newExpireCount = expireCount - removedCount;
|
|
+ if (newExpireCount > 0) {
|
|
+ entry.setValue(newExpireCount);
|
|
+ } else {
|
|
+ iterator1.remove();
|
|
+ }
|
|
+ }
|
|
}
|
|
- }
|
|
|
|
- if (chunkToExpireCount.isEmpty()) {
|
|
- this.sectionToChunkToExpireCount.remove(sectionKey);
|
|
}
|
|
+ if (chunkToExpireCount.isEmpty()) { this.sectionToChunkToExpireCount.remove(sectionKey); }
|
|
} finally {
|
|
this.ticketLockArea.unlock(ticketLock);
|
|
}
|
|
@@ -812,6 +841,7 @@ public final class ChunkHolderManager {
|
|
this.processTicketUpdates();
|
|
}
|
|
|
|
+
|
|
public NewChunkHolder getChunkHolder(final int chunkX, final int chunkZ) {
|
|
return this.chunkHolders.get(CoordinateUtils.getChunkKey(chunkX, chunkZ));
|
|
}
|