Optimize thread providers

This commit is contained in:
Felix Cravic 2020-08-15 01:18:49 +02:00
parent 1d047b5de3
commit 0d4689a367
6 changed files with 45 additions and 49 deletions

View File

@ -52,7 +52,10 @@ public final class UpdateManager {
final long time = System.currentTimeMillis();
// Server tick (instance/chunk/entity)
threadProvider.update(time);
// Synchronize with the update manager instance, like the signal for chunk load/unload
synchronized (this) {
threadProvider.update(time);
}
// Waiting players update (newly connected waiting to get into the server)
entityManager.updateWaitingPlayers();

View File

@ -16,7 +16,7 @@ public abstract class DataType<T> {
/**
* Decode the data type
*
* @param packetReader the data readerr
* @param packetReader the data reader
* @return the decoded value
*/
public abstract T decode(PacketReader packetReader);

View File

@ -5,18 +5,19 @@ import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.network.packet.PacketReader;
import net.minestom.server.network.packet.PacketWriter;
import org.jglrxavpok.hephaistos.nbt.NBTException;
public class InventoryData extends DataType<Inventory> {
@Override
public void encode(PacketWriter packetWriter, Inventory value) {
InventoryType inventoryType = value.getInventoryType();
int size = inventoryType.getAdditionalSlot();
final InventoryType inventoryType = value.getInventoryType();
final int size = inventoryType.getAdditionalSlot();
// Inventory title & type
packetWriter.writeSizedString(value.getTitle());
packetWriter.writeSizedString(inventoryType.name());
// Write all item stacks
for (int i = 0; i < size; i++) {
packetWriter.writeItemStack(value.getItemStack(i));
}
@ -24,12 +25,13 @@ public class InventoryData extends DataType<Inventory> {
@Override
public Inventory decode(PacketReader packetReader) {
String title = packetReader.readSizedString();
InventoryType inventoryType = InventoryType.valueOf(packetReader.readSizedString());
int size = inventoryType.getAdditionalSlot();
final String title = packetReader.readSizedString();
final InventoryType inventoryType = InventoryType.valueOf(packetReader.readSizedString());
final int size = inventoryType.getAdditionalSlot();
Inventory inventory = new Inventory(inventoryType, title);
// Read all item stacks
for (int i = 0; i < size; i++) {
inventory.setItemStack(i, packetReader.readSlot());
}

View File

@ -4,7 +4,6 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongArraySet;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.chunk.ChunkUtils;
@ -22,12 +21,12 @@ public class PerGroupChunkProvider extends ThreadProvider {
/**
* Chunk -> its chunk group
*/
private Map<Instance, Long2ObjectMap<LongSet>> instanceChunksGroupMap = new ConcurrentHashMap<>();
private final Map<Instance, Long2ObjectMap<LongSet>> instanceChunksGroupMap = new ConcurrentHashMap<>();
/**
* Used to know to which instance is linked a Set of chunks
*/
private Map<Instance, Map<LongSet, Instance>> instanceInstanceMap = new ConcurrentHashMap<>();
private final Map<Instance, Map<LongSet, Instance>> instanceInstanceMap = new ConcurrentHashMap<>();
@Override
public void onChunkLoad(Instance instance, int chunkX, int chunkZ) {
@ -107,18 +106,14 @@ public class PerGroupChunkProvider extends ThreadProvider {
@Override
public void update(long time) {
// Set of already-updated instances this tick
final Set<Instance> updatedInstance = new HashSet<>();
instanceInstanceMap.entrySet().forEach(entry -> {
final Instance instance = entry.getKey();
final Map<LongSet, Instance> instanceMap = entry.getValue();
Set<Instance> updatedInstance = new HashSet<>();
instanceInstanceMap.forEach((instance, instanceMap) -> {
// True if the instance ended its tick call
AtomicBoolean instanceUpdated = new AtomicBoolean(false);
// Update all the chunks + instances
for (Map.Entry<LongSet, Instance> ent : instanceMap.entrySet()) {
final LongSet chunksIndexes = ent.getKey();
instanceMap.keySet().forEach(chunksIndexes -> {
final boolean shouldUpdateInstance = updatedInstance.add(instance);
pool.execute(() -> {
@ -133,21 +128,11 @@ public class PerGroupChunkProvider extends ThreadProvider {
while (!instanceUpdated.get()) {
}
for (long chunkIndex : chunksIndexes) {
final int[] chunkCoordinates = ChunkUtils.getChunkCoord(chunkIndex);
final Chunk chunk = instance.getChunk(chunkCoordinates[0], chunkCoordinates[1]);
if (!ChunkUtils.isLoaded(chunk)) {
continue;
}
updateChunk(instance, chunk, time);
updateEntities(instance, chunk, time);
}
// Tick all this chunk group
chunksIndexes.forEach((long chunkIndex) -> processChunkTick(instance, chunkIndex, time));
});
}
});
});
}

View File

@ -2,7 +2,6 @@ package net.minestom.server.thread;
import it.unimi.dsi.fastutil.longs.LongArraySet;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.chunk.ChunkUtils;
@ -35,26 +34,14 @@ public class PerInstanceThreadProvider extends ThreadProvider {
@Override
public void update(long time) {
for (Map.Entry<Instance, LongSet> entry : instanceChunkMap.entrySet()) {
final Instance instance = entry.getKey();
final LongSet chunkIndexes = entry.getValue();
instanceChunkMap.forEach((instance, chunkIndexes) -> {
pool.execute(() -> {
// Tick instance
updateInstance(instance, time);
for (long chunkIndex : chunkIndexes) {
final int[] chunkCoordinates = ChunkUtils.getChunkCoord(chunkIndex);
final Chunk chunk = instance.getChunk(chunkCoordinates[0], chunkCoordinates[1]);
if (!ChunkUtils.isLoaded(chunk))
continue;
updateChunk(instance, chunk, time);
updateEntities(instance, chunk, time);
}
// Tick chunks
chunkIndexes.forEach((long chunkIndex) -> processChunkTick(instance, chunkIndex, time));
});
}
});
}
private LongSet getChunkCoordinates(Instance instance) {

View File

@ -4,6 +4,7 @@ import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.*;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.thread.MinestomThread;
import java.util.Set;
@ -82,6 +83,24 @@ public abstract class ThreadProvider {
* INSTANCE UPDATE
*/
/**
* Process a whole tick for a chunk
*
* @param instance the instance of the chunk
* @param chunkIndex the index of the chunk {@link ChunkUtils#getChunkIndex(int, int)}
* @param time the time of the update in milliseconds
*/
protected void processChunkTick(Instance instance, long chunkIndex, long time) {
final int[] chunkCoordinates = ChunkUtils.getChunkCoord(chunkIndex);
final Chunk chunk = instance.getChunk(chunkCoordinates[0], chunkCoordinates[1]);
if (!ChunkUtils.isLoaded(chunk))
return;
updateChunk(instance, chunk, time);
updateEntities(instance, chunk, time);
}
/**
* Execute an instance tick
*