mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-02 14:38:26 +01:00
Reduce chunk entities Set allocation
This commit is contained in:
parent
266ecd5b64
commit
a0bb437c4c
@ -1434,10 +1434,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
*/
|
||||
public void refreshVisibleChunks(@NotNull Chunk newChunk) {
|
||||
// Previous chunks indexes
|
||||
final long[] lastVisibleChunks = viewableChunks.stream().mapToLong(viewableChunks ->
|
||||
ChunkUtils.getChunkIndex(viewableChunks.getChunkX(), viewableChunks.getChunkZ())
|
||||
).toArray();
|
||||
|
||||
final long[] lastVisibleChunks = viewableChunks.stream().mapToLong(ChunkUtils::getChunkIndex).toArray();
|
||||
// New chunks indexes
|
||||
final long[] updatedVisibleChunks = ChunkUtils.getChunksInRange(newChunk.toPosition(), getChunkRange());
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.minestom.server.instance;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.kyori.adventure.identity.Identity;
|
||||
import net.kyori.adventure.pointer.Pointers;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
@ -83,8 +85,8 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
|
||||
protected final Set<EntityCreature> creatures = ConcurrentHashMap.newKeySet();
|
||||
protected final Set<ExperienceOrb> experienceOrbs = ConcurrentHashMap.newKeySet();
|
||||
// Entities per chunk
|
||||
protected final Map<Long, Set<Entity>> chunkEntities = new ConcurrentHashMap<>();
|
||||
private final Object entitiesLock = new Object(); // Lock used to prevent the entities Set and Map to be subject to race condition
|
||||
protected final Object entitiesLock = new Object(); // Lock used to prevent the entities Set and Map to be subject to race condition
|
||||
protected final Long2ObjectMap<Set<Entity>> chunkEntities = new Long2ObjectOpenHashMap<>();
|
||||
|
||||
// the uuid of this instance
|
||||
protected UUID uniqueId;
|
||||
@ -486,9 +488,12 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
|
||||
public @NotNull Set<Entity> getChunkEntities(Chunk chunk) {
|
||||
if (!ChunkUtils.isLoaded(chunk))
|
||||
return Collections.emptySet();
|
||||
|
||||
final long index = ChunkUtils.getChunkIndex(chunk.getChunkX(), chunk.getChunkZ());
|
||||
final Set<Entity> entities = getEntitiesInChunk(index);
|
||||
final Set<Entity> entities;
|
||||
synchronized (entitiesLock) {
|
||||
if ((entities = chunkEntities.get(ChunkUtils.getChunkIndex(chunk))) == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableSet(entities);
|
||||
}
|
||||
|
||||
@ -642,15 +647,15 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
|
||||
final long oldIndex = ChunkUtils.getChunkIndex(lastChunk);
|
||||
final long newIndex = ChunkUtils.getChunkIndex(newChunk);
|
||||
synchronized (entitiesLock) {
|
||||
getEntitiesInChunk(oldIndex).remove(entity);
|
||||
getEntitiesInChunk(newIndex).add(entity);
|
||||
removeEntityChunk(oldIndex, entity);
|
||||
addEntityChunk(newIndex, entity);
|
||||
}
|
||||
}
|
||||
|
||||
private void UNSAFE_addEntityToChunk(@NotNull Entity entity, @NotNull Chunk chunk) {
|
||||
final long chunkIndex = ChunkUtils.getChunkIndex(chunk);
|
||||
synchronized (entitiesLock) {
|
||||
getEntitiesInChunk(chunkIndex).add(entity);
|
||||
addEntityChunk(chunkIndex, entity);
|
||||
this.entities.add(entity);
|
||||
if (entity instanceof Player) {
|
||||
this.players.add((Player) entity);
|
||||
@ -665,7 +670,7 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
|
||||
private void UNSAFE_removeEntityFromChunk(@NotNull Entity entity, @NotNull Chunk chunk) {
|
||||
final long chunkIndex = ChunkUtils.getChunkIndex(chunk);
|
||||
synchronized (entitiesLock) {
|
||||
getEntitiesInChunk(chunkIndex).remove(entity);
|
||||
removeEntityChunk(chunkIndex, entity);
|
||||
this.entities.remove(entity);
|
||||
if (entity instanceof Player) {
|
||||
this.players.remove(entity);
|
||||
@ -677,9 +682,18 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Set<Entity> getEntitiesInChunk(long index) {
|
||||
return chunkEntities.computeIfAbsent(index, i -> ConcurrentHashMap.newKeySet());
|
||||
private void addEntityChunk(long index, Entity entity) {
|
||||
this.chunkEntities.computeIfAbsent(index, i -> ConcurrentHashMap.newKeySet()).add(entity);
|
||||
}
|
||||
|
||||
private void removeEntityChunk(long index, Entity entity) {
|
||||
var chunkEntities = this.chunkEntities.get(index);
|
||||
if (chunkEntities != null) {
|
||||
chunkEntities.remove(entity);
|
||||
if (chunkEntities.isEmpty()) {
|
||||
this.chunkEntities.remove(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -566,7 +566,9 @@ public class InstanceContainer extends Instance {
|
||||
|
||||
// Clear cache
|
||||
this.chunks.remove(index);
|
||||
this.chunkEntities.remove(index);
|
||||
synchronized (entitiesLock){
|
||||
this.chunkEntities.remove(index);
|
||||
}
|
||||
|
||||
chunk.unload();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user