Improve CachedPacket

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2021-10-19 12:41:34 +02:00
parent 11d0f82b86
commit 3685bf22b7
2 changed files with 21 additions and 19 deletions

View File

@ -39,6 +39,7 @@ public class DynamicChunk extends Chunk {
protected final Int2ObjectOpenHashMap<Block> entries = new Int2ObjectOpenHashMap<>();
protected final Int2ObjectOpenHashMap<Block> tickableMap = new Int2ObjectOpenHashMap<>();
private long lastChange;
private final CachedPacket chunkCache = new CachedPacket(this::createChunkPacket);
private final CachedPacket lightCache = new CachedPacket(this::createLightPacket);
@ -48,8 +49,9 @@ public class DynamicChunk extends Chunk {
@Override
public void setBlock(int x, int y, int z, @NotNull Block block) {
this.chunkCache.updateTimestamp();
this.lightCache.updateTimestamp();
this.lastChange = System.currentTimeMillis();
this.chunkCache.invalidate();
this.lightCache.invalidate();
// Update pathfinder
if (columnarSpace != null) {
final ColumnarOcclusionFieldList columnarOcclusionFieldList = columnarSpace.occlusionFields();
@ -118,7 +120,7 @@ public class DynamicChunk extends Chunk {
@Override
public long getLastChangeTime() {
return chunkCache.lastChange();
return lastChange;
}
@Override

View File

@ -3,39 +3,39 @@ package net.minestom.server.network.packet;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.utils.PacketUtils;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.lang.ref.SoftReference;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.function.Supplier;
@ApiStatus.Internal
public final class CachedPacket {
private static final AtomicIntegerFieldUpdater<CachedPacket> UPDATER = AtomicIntegerFieldUpdater.newUpdater(CachedPacket.class, "updated");
private final Supplier<ServerPacket> supplier;
private volatile long lastChange;
private volatile long packetTimestamp;
// 0 means that the reference needs to be updated
// Anything else (currently 1) means that the packet is up-to-date
private volatile int updated = 0;
private SoftReference<FramedPacket> packet;
public CachedPacket(Supplier<ServerPacket> supplier) {
public CachedPacket(@NotNull Supplier<@NotNull ServerPacket> supplier) {
this.supplier = supplier;
}
public void updateTimestamp() {
this.lastChange = System.currentTimeMillis();
public void invalidate() {
this.updated = 0;
}
public FramedPacket retrieve() {
final long lastChange = this.lastChange;
final long timestamp = packetTimestamp;
final var ref = packet;
FramedPacket cache = ref != null ? ref.get() : null;
if (cache == null || lastChange > timestamp) {
public @NotNull FramedPacket retrieve() {
SoftReference<FramedPacket> ref;
FramedPacket cache;
if (updated == 0 ||
((ref = packet) == null ||
(cache = ref.get()) == null)) {
cache = PacketUtils.allocateTrimmedPacket(supplier.get());
this.packet = new SoftReference<>(cache);
this.packetTimestamp = lastChange;
UPDATER.compareAndSet(this, 0, 1);
}
return cache;
}
public long lastChange() {
return lastChange;
}
}