mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-27 11:38:03 +01:00
Simplify CachedPacket
This commit is contained in:
parent
bb1b1e53d7
commit
7df51ef606
@ -11,36 +11,26 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a packet that is compute only when required (either due to memory demand or invalidated data)
|
* Represents a packet that is only computed when required (either due to memory demand or invalidated data)
|
||||||
* <p>
|
* <p>
|
||||||
* The {@link FramedPacket} is stored in a {@link SoftReference} and is invalidated when the {@link #invalidate()} method is called.
|
* The cache is stored in a {@link SoftReference} and is invalidated when {@link #invalidate()} is called.
|
||||||
* <p>
|
* <p>
|
||||||
* The {@link ServerPacket} may be computed dynamically in another thread, or be a constant to potentially
|
* Packet supplier must be thread-safe.
|
||||||
* improve retrieval performance at the cost of the object staying in the heap.
|
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
public final class CachedPacket implements SendablePacket {
|
public final class CachedPacket implements SendablePacket {
|
||||||
private static final AtomicIntegerFieldUpdater<CachedPacket> UPDATER = AtomicIntegerFieldUpdater.newUpdater(CachedPacket.class, "updated");
|
private static final AtomicIntegerFieldUpdater<CachedPacket> UPDATER =
|
||||||
|
AtomicIntegerFieldUpdater.newUpdater(CachedPacket.class, "updated");
|
||||||
private final Supplier<ServerPacket> packetSupplier;
|
private final Supplier<ServerPacket> packetSupplier;
|
||||||
// 0 means that the reference needs to be updated
|
// 0 means that the reference needs to be updated
|
||||||
// Anything else (currently 1) means that the packet is up-to-date
|
// Anything else (currently 1) means that the packet is up-to-date
|
||||||
private volatile int updated = 0;
|
private volatile int updated = 0;
|
||||||
private SoftReference<FramedPacket> packet;
|
private SoftReference<FramedPacket> packet;
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new cached packet that will force the allocation of a new {@link ServerPacket}
|
|
||||||
* during invalidation due to memory constraint or invalidation.
|
|
||||||
* <p>
|
|
||||||
* {@code packetSupplier} must be thread-safe.
|
|
||||||
*/
|
|
||||||
public CachedPacket(@NotNull Supplier<@NotNull ServerPacket> packetSupplier) {
|
public CachedPacket(@NotNull Supplier<@NotNull ServerPacket> packetSupplier) {
|
||||||
this.packetSupplier = packetSupplier;
|
this.packetSupplier = packetSupplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new cached packet from a constant {@link ServerPacket}
|
|
||||||
* which will be the return value of {@link #packet()}.
|
|
||||||
*/
|
|
||||||
public CachedPacket(@NotNull ServerPacket packet) {
|
public CachedPacket(@NotNull ServerPacket packet) {
|
||||||
this(() -> packet);
|
this(() -> packet);
|
||||||
}
|
}
|
||||||
@ -49,12 +39,6 @@ public final class CachedPacket implements SendablePacket {
|
|||||||
this.updated = 0;
|
this.updated = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the packet object without allocating a buffer.
|
|
||||||
* <p>
|
|
||||||
* This method can be useful in case the payload is not important (e.g. for packet listening),
|
|
||||||
* but {@link #toBuffer()} and {@link #toFramedPacket()} should be privileged otherwise.
|
|
||||||
*/
|
|
||||||
public @NotNull ServerPacket packet() {
|
public @NotNull ServerPacket packet() {
|
||||||
FramedPacket cache;
|
FramedPacket cache;
|
||||||
if (updated == 1 && (cache = packet.get()) != null)
|
if (updated == 1 && (cache = packet.get()) != null)
|
||||||
@ -62,24 +46,17 @@ public final class CachedPacket implements SendablePacket {
|
|||||||
return packetSupplier.get();
|
return packetSupplier.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull ByteBuffer toBuffer() {
|
public @NotNull ByteBuffer body() {
|
||||||
FramedPacket cache = updatedCache();
|
FramedPacket cache = updatedCache();
|
||||||
return cache != null ? cache.body() : PacketUtils.createFramedPacket(packet());
|
return cache != null ? cache.body() : PacketUtils.createFramedPacket(packet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull FramedPacket toFramedPacket() {
|
|
||||||
FramedPacket cache = updatedCache();
|
|
||||||
return cache != null ? cache : PacketUtils.allocateTrimmedPacket(packet());
|
|
||||||
}
|
|
||||||
|
|
||||||
private @Nullable FramedPacket updatedCache() {
|
private @Nullable FramedPacket updatedCache() {
|
||||||
if (!PacketUtils.CACHED_PACKET)
|
if (!PacketUtils.CACHED_PACKET)
|
||||||
return null;
|
return null;
|
||||||
SoftReference<FramedPacket> ref;
|
SoftReference<FramedPacket> ref;
|
||||||
FramedPacket cache;
|
FramedPacket cache;
|
||||||
if (updated == 0 ||
|
if (updated == 0 || ((ref = packet) == null || (cache = ref.get()) == null)) {
|
||||||
((ref = packet) == null ||
|
|
||||||
(cache = ref.get()) == null)) {
|
|
||||||
cache = PacketUtils.allocateTrimmedPacket(packet());
|
cache = PacketUtils.allocateTrimmedPacket(packet());
|
||||||
this.packet = new SoftReference<>(cache);
|
this.packet = new SoftReference<>(cache);
|
||||||
UPDATER.compareAndSet(this, 0, 1);
|
UPDATER.compareAndSet(this, 0, 1);
|
||||||
|
@ -356,7 +356,7 @@ public class PlayerSocketConnection extends PlayerConnection {
|
|||||||
} else if (packet instanceof FramedPacket framedPacket) {
|
} else if (packet instanceof FramedPacket framedPacket) {
|
||||||
writeFramedPacketSync(framedPacket);
|
writeFramedPacketSync(framedPacket);
|
||||||
} else if (packet instanceof CachedPacket cachedPacket) {
|
} else if (packet instanceof CachedPacket cachedPacket) {
|
||||||
writeBufferSync(cachedPacket.toBuffer());
|
writeBufferSync(cachedPacket.body());
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Unknown packet type: " + packet.getClass().getName());
|
throw new RuntimeException("Unknown packet type: " + packet.getClass().getName());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user