From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Taiyou06 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 holderMap = ChunkHolderManager.this.chunkHolders; for (final Iterator 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> 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> 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)); }