Skip to content

Commit

Permalink
Potential optimization for too many chunks getting loaded when recalc…
Browse files Browse the repository at this point in the history
…ulating entities for islands (#1323)
  • Loading branch information
OmerBenGera committed Aug 27, 2022
1 parent b6e648f commit 4f31996
Showing 1 changed file with 27 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,10 @@
import com.bgsoftware.superiorskyblock.api.island.algorithms.IslandEntitiesTrackerAlgorithm;
import com.bgsoftware.superiorskyblock.api.key.Key;
import com.bgsoftware.superiorskyblock.api.key.KeyMap;
import com.bgsoftware.superiorskyblock.core.threads.BukkitExecutor;
import com.bgsoftware.superiorskyblock.core.key.KeyMapImpl;
import com.bgsoftware.superiorskyblock.core.collections.CompletableFutureList;
import com.bgsoftware.superiorskyblock.core.debug.PluginDebugger;
import com.bgsoftware.superiorskyblock.core.key.KeyMapImpl;
import com.bgsoftware.superiorskyblock.world.BukkitEntities;
import com.bgsoftware.superiorskyblock.island.IslandUtils;
import com.bgsoftware.superiorskyblock.world.chunk.ChunkLoadReason;
import com.google.common.base.Preconditions;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.entity.Entity;

import java.util.Collections;
Expand Down Expand Up @@ -106,56 +100,43 @@ public void recalculateEntityCounts() {
return;

this.beingRecalculated = true;
this.lastCalculateTime = currentTime;

clearEntityCounts();
try {
this.lastCalculateTime = currentTime;

KeyMap<Integer> recalculatedEntityCounts = KeyMapImpl.createConcurrentHashMap();
CompletableFutureList<Chunk> chunks = new CompletableFutureList<>();
clearEntityCounts();

for (World.Environment environment : World.Environment.values()) {
try {
World world = island.getCenter(environment).getWorld();
chunks.addAll(IslandUtils.getAllChunksAsync(island, world, true, true, ChunkLoadReason.ENTITIES_RECALCULATE, chunk -> {
for (Entity entity : chunk.getEntities()) {
if (BukkitEntities.canBypassEntityLimit(entity))
continue;
KeyMap<Integer> recalculatedEntityCounts = KeyMapImpl.createConcurrentHashMap();

Key key = BukkitEntities.getLimitEntityType(entity);
island.getLoadedChunks(true, true).forEach(chunk -> {
for (Entity entity : chunk.getEntities()) {
if (BukkitEntities.canBypassEntityLimit(entity))
continue;

if (!canTrackEntity(key))
continue;
Key key = BukkitEntities.getLimitEntityType(entity);

int currentEntityAmount = recalculatedEntityCounts.getOrDefault(key, 0);
recalculatedEntityCounts.put(key, currentEntityAmount + 1);
}
}));
} catch (Exception ignored) {
}
}
if (!canTrackEntity(key))
continue;

BukkitExecutor.async(() -> {
try {
//Waiting for all the chunks to load
chunks.forEachCompleted(chunk -> {
}, error -> {
});

if (!this.entityCounts.isEmpty()) {
for (Map.Entry<Key, Integer> entry : this.entityCounts.entrySet()) {
Integer currentAmount = recalculatedEntityCounts.remove(entry.getKey());
if (currentAmount != null)
entry.setValue(entry.getValue() + currentAmount);
}
int currentEntityAmount = recalculatedEntityCounts.getOrDefault(key, 0);
recalculatedEntityCounts.put(key, currentEntityAmount + 1);
}
});

if (!recalculatedEntityCounts.isEmpty()) {
this.entityCounts.putAll(recalculatedEntityCounts);
if (!this.entityCounts.isEmpty()) {
for (Map.Entry<Key, Integer> entry : this.entityCounts.entrySet()) {
Integer currentAmount = recalculatedEntityCounts.remove(entry.getKey());
if (currentAmount != null)
entry.setValue(entry.getValue() + currentAmount);
}
} finally {
beingRecalculated = false;
}
});

if (!recalculatedEntityCounts.isEmpty()) {
this.entityCounts.putAll(recalculatedEntityCounts);
}
} finally {
beingRecalculated = false;
}
}

private boolean canTrackEntity(Key key) {
Expand Down

0 comments on commit 4f31996

Please sign in to comment.