mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-01 14:07:43 +01:00
Allow tag write without allocation if compatible with the previous entry
This commit is contained in:
parent
af28caad9e
commit
7be96b7679
@ -60,7 +60,12 @@ final class TagHandlerImpl implements TagHandler {
|
|||||||
SPMCMap entries = local.entries;
|
SPMCMap entries = local.entries;
|
||||||
if (present) {
|
if (present) {
|
||||||
if (!isView) {
|
if (!isView) {
|
||||||
entries.put(tagIndex, valueToEntry(local, tag, value));
|
Entry previous = entries.get(tagIndex);
|
||||||
|
if (previous != null && previous.tag().shareValue(tag)) {
|
||||||
|
previous.updateValue(value);
|
||||||
|
} else {
|
||||||
|
entries.put(tagIndex, valueToEntry(local, tag, value));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
local.updateContent((NBTCompound) tag.entry.write(value));
|
local.updateContent((NBTCompound) tag.entry.write(value));
|
||||||
return;
|
return;
|
||||||
@ -163,7 +168,7 @@ final class TagHandlerImpl implements TagHandler {
|
|||||||
// Slow path is taken if the entry comes from a Structure tag, requiring conversion from NBT
|
// Slow path is taken if the entry comes from a Structure tag, requiring conversion from NBT
|
||||||
TagHandlerImpl tmp = local;
|
TagHandlerImpl tmp = local;
|
||||||
local = new TagHandlerImpl(tmp);
|
local = new TagHandlerImpl(tmp);
|
||||||
if (entry != null && entry.updatedNbt() instanceof NBTCompound compound) {
|
if (entry != null && entry.nbt() instanceof NBTCompound compound) {
|
||||||
local.updateContent(compound);
|
local.updateContent(compound);
|
||||||
}
|
}
|
||||||
tmp.entries.put(pathIndex, new PathEntry(path.name(), local));
|
tmp.entries.put(pathIndex, new PathEntry(path.name(), local));
|
||||||
@ -179,7 +184,7 @@ final class TagHandlerImpl implements TagHandler {
|
|||||||
if (!entries.isEmpty()) {
|
if (!entries.isEmpty()) {
|
||||||
MutableNBTCompound tmp = new MutableNBTCompound();
|
MutableNBTCompound tmp = new MutableNBTCompound();
|
||||||
for (Entry<?> entry : entries.values()) {
|
for (Entry<?> entry : entries.values()) {
|
||||||
if (entry != null) tmp.put(entry.tag().getKey(), entry.updatedNbt());
|
if (entry != null) tmp.put(entry.tag().getKey(), entry.nbt());
|
||||||
}
|
}
|
||||||
cache = new Cache(entries.clone(), tmp.toCompound());
|
cache = new Cache(entries.clone(), tmp.toCompound());
|
||||||
} else cache = Cache.EMPTY;
|
} else cache = Cache.EMPTY;
|
||||||
@ -214,7 +219,7 @@ final class TagHandlerImpl implements TagHandler {
|
|||||||
return (T) entry.value();
|
return (T) entry.value();
|
||||||
}
|
}
|
||||||
// Value must be parsed from nbt if the tag is different
|
// Value must be parsed from nbt if the tag is different
|
||||||
final NBT nbt = entry.updatedNbt();
|
final NBT nbt = entry.nbt();
|
||||||
final Serializers.Entry<T, NBT> serializerEntry = tag.entry;
|
final Serializers.Entry<T, NBT> serializerEntry = tag.entry;
|
||||||
final NBTType<NBT> type = serializerEntry.nbtType();
|
final NBTType<NBT> type = serializerEntry.nbtType();
|
||||||
return type == null || type == nbt.getID() ? serializerEntry.read(nbt) : tag.createDefault();
|
return type == null || type == nbt.getID() ? serializerEntry.read(nbt) : tag.createDefault();
|
||||||
@ -230,7 +235,7 @@ final class TagHandlerImpl implements TagHandler {
|
|||||||
return null;
|
return null;
|
||||||
if (entry instanceof PathEntry pathEntry) {
|
if (entry instanceof PathEntry pathEntry) {
|
||||||
result = pathEntry.value;
|
result = pathEntry.value;
|
||||||
} else if (entry.updatedNbt() instanceof NBTCompound compound) {
|
} else if (entry.nbt() instanceof NBTCompound compound) {
|
||||||
// Slow path forcing a conversion of the structure to NBTCompound
|
// Slow path forcing a conversion of the structure to NBTCompound
|
||||||
// TODO should the handler be cached inside the entry?
|
// TODO should the handler be cached inside the entry?
|
||||||
result = fromCompound(compound);
|
result = fromCompound(compound);
|
||||||
@ -260,12 +265,14 @@ final class TagHandlerImpl implements TagHandler {
|
|||||||
|
|
||||||
T value();
|
T value();
|
||||||
|
|
||||||
NBT updatedNbt();
|
NBT nbt();
|
||||||
|
|
||||||
|
void updateValue(T value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class TagEntry<T> implements Entry<T> {
|
private static final class TagEntry<T> implements Entry<T> {
|
||||||
private final Tag<T> tag;
|
private final Tag<T> tag;
|
||||||
private final T value;
|
volatile T value;
|
||||||
volatile NBT nbt;
|
volatile NBT nbt;
|
||||||
|
|
||||||
TagEntry(Tag<T> tag, T value) {
|
TagEntry(Tag<T> tag, T value) {
|
||||||
@ -284,11 +291,17 @@ final class TagHandlerImpl implements TagHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NBT updatedNbt() {
|
public NBT nbt() {
|
||||||
NBT nbt = this.nbt;
|
NBT nbt = this.nbt;
|
||||||
if (nbt == null) this.nbt = nbt = tag.entry.write(value);
|
if (nbt == null) this.nbt = nbt = tag.entry.write(value);
|
||||||
return nbt;
|
return nbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateValue(T value) {
|
||||||
|
this.value = value;
|
||||||
|
this.nbt = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private record PathEntry(Tag<TagHandlerImpl> tag,
|
private record PathEntry(Tag<TagHandlerImpl> tag,
|
||||||
@ -298,9 +311,14 @@ final class TagHandlerImpl implements TagHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NBTCompound updatedNbt() {
|
public NBTCompound nbt() {
|
||||||
return value.asCompound();
|
return value.asCompound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateValue(TagHandlerImpl value) {
|
||||||
|
throw new UnsupportedOperationException("Cannot update a path entry");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class SPMCMap extends Int2ObjectOpenHashMap<Entry<?>> {
|
static final class SPMCMap extends Int2ObjectOpenHashMap<Entry<?>> {
|
||||||
|
Loading…
Reference in New Issue
Block a user