diff --git a/shiroha-server/src/main/java/io/nanachiyo0721/shiroha/utils/ReferenceCountingChunkLoader.java b/shiroha-server/src/main/java/io/nanachiyo0721/shiroha/utils/ReferenceCountingChunkLoader.java index 2781f3a..8a40337 100644 --- a/shiroha-server/src/main/java/io/nanachiyo0721/shiroha/utils/ReferenceCountingChunkLoader.java +++ b/shiroha-server/src/main/java/io/nanachiyo0721/shiroha/utils/ReferenceCountingChunkLoader.java @@ -218,34 +218,45 @@ public class ReferenceCountingChunkLoader { final ReferenceCountData[] toRemoveTicket = new ReferenceCountData[1]; - for (ConcurrentChainedLong2ReferenceHashTable.TableEntry counterEntry : this.referenceCounters.entrySet()) { - final long coord = counterEntry.getKey(); - final ReferenceCountData counterData = counterEntry.getValue(); + final it.unimi.dsi.fastutil.longs.LongIterator sectionsIterator = currentRegion.getOwnedSectionsUnsynchronised(); + while (sectionsIterator.hasNext()) { + final long sectionKey = sectionsIterator.nextLong(); + final int sectionX = CoordinateUtils.getChunkX(sectionKey); + final int sectionZ = CoordinateUtils.getChunkZ(sectionKey); - if (currentRegion == this.world.regioniser.getRegionAtUnsynchronised(CoordinateUtils.getChunkX(coord), CoordinateUtils.getChunkZ(coord))) { - long curr = counterData.referenceTTL.get(); - if (curr == (curr = counterData.referenceTTL.compareAndExchange(curr, curr - 1))) { - if (counterData.referenceCount.get() != 0L) { - counterData.referenceTTL.set(MAX_CHUNK_TTL_TICKS); - continue; - } + final int chunkX = sectionX << this.world.regioniser.sectionChunkShift; + final int chunkZ = sectionZ << this.world.regioniser.sectionChunkShift; + final long coord = CoordinateUtils.getChunkKey(chunkX, chunkZ); + final ReferenceCountData counterData = this.referenceCounters.get(coord); - if (curr <= 0) { - this.referenceCounters.computeIfPresent(coord, (final long keyInMap, final ReferenceCountData valueInMap) -> { - if (valueInMap.referenceCount.get() != 0L) { - valueInMap.referenceTTL.set(MAX_CHUNK_TTL_TICKS); - return valueInMap; - } + // removed + if (counterData == null) { + continue; + } - toRemoveTicket[0] = valueInMap; + // do ttl + long curr = counterData.referenceTTL.get(); + if (curr == (curr = counterData.referenceTTL.compareAndExchange(curr, curr - 1))) { + if (counterData.referenceCount.get() != 0L) { + counterData.referenceTTL.set(MAX_CHUNK_TTL_TICKS); + continue; + } - return null; - }); - - if (toRemoveTicket[0] != null) { - this.removeTicket(coord, toRemoveTicket[0].id); - toRemoveTicket[0] = null; + if (curr <= 0) { + this.referenceCounters.computeIfPresent(coord, (final long keyInMap, final ReferenceCountData valueInMap) -> { + if (valueInMap.referenceCount.get() != 0L) { + valueInMap.referenceTTL.set(MAX_CHUNK_TTL_TICKS); + return valueInMap; } + + toRemoveTicket[0] = valueInMap; + + return null; + }); + + if (toRemoveTicket[0] != null) { + this.removeTicket(coord, toRemoveTicket[0].id); + toRemoveTicket[0] = null; } } }