mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-01 14:07:43 +01:00
Improve read performance with different tag
This commit is contained in:
parent
2301ad9976
commit
043c139b91
@ -178,6 +178,12 @@ public class Tag<T> {
|
||||
write(nbtCompound, (T) value);
|
||||
}
|
||||
|
||||
final boolean shareValue(@NotNull Tag<?> other) {
|
||||
// Verify if these 2 tags can share the same cached value
|
||||
// Key/Default value/Path are ignored
|
||||
return this == other || this.readFunction == other.readFunction;
|
||||
}
|
||||
|
||||
public static @NotNull Tag<Byte> Byte(@NotNull String key) {
|
||||
return tag(key, NBTByte::getValue, NBT::Byte);
|
||||
}
|
||||
|
@ -172,6 +172,12 @@ final class TagHandlerImpl implements TagHandler {
|
||||
this.tag = tag;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
NBT updatedNbt() {
|
||||
NBT nbt = this.nbt;
|
||||
if (nbt == null) this.nbt = nbt = tag.writeFunction.apply(value);
|
||||
return nbt;
|
||||
}
|
||||
}
|
||||
|
||||
private record Cache(Entry<?>[] entries, NBTCompound compound) implements TagReadable {
|
||||
@ -196,6 +202,10 @@ final class TagHandlerImpl implements TagHandler {
|
||||
}
|
||||
if (entry.value instanceof TagHandlerImpl handler) {
|
||||
entries = handler.entries;
|
||||
} else if (entry.updatedNbt() instanceof NBTCompound compound) {
|
||||
var tmp = new TagHandlerImpl();
|
||||
tmp.updateContent(compound);
|
||||
entries = tmp.entries;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -206,14 +216,13 @@ final class TagHandlerImpl implements TagHandler {
|
||||
if (value instanceof TagHandlerImpl)
|
||||
throw new IllegalStateException("Cannot read path-able tag " + tag.getKey());
|
||||
final Tag entryTag = entry.tag;
|
||||
if (entryTag == tag) {
|
||||
if (entryTag.shareValue(tag)) {
|
||||
// Tag is the same, return the value
|
||||
//noinspection unchecked
|
||||
return (T) value;
|
||||
}
|
||||
// Value must be parsed from nbt if the tag is different
|
||||
NBT nbt = entry.nbt;
|
||||
if (nbt == null) entry.nbt = nbt = (NBT) entryTag.writeFunction.apply(value);
|
||||
final NBT nbt = entry.updatedNbt();
|
||||
try {
|
||||
return tag.readFunction.apply(nbt);
|
||||
} catch (ClassCastException e) {
|
||||
|
53
src/test/java/net/minestom/server/tag/TagEqualityTest.java
Normal file
53
src/test/java/net/minestom/server/tag/TagEqualityTest.java
Normal file
@ -0,0 +1,53 @@
|
||||
package net.minestom.server.tag;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Test tags that can share cached values.
|
||||
*/
|
||||
public class TagEqualityTest {
|
||||
|
||||
@Test
|
||||
public void same() {
|
||||
var tag = Tag.String("test");
|
||||
assertTrue(tag.shareValue(tag));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void similar() {
|
||||
var tag = Tag.String("test");
|
||||
var tag2 = Tag.String("test");
|
||||
assertTrue(tag.shareValue(tag2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void differentDefault() {
|
||||
var tag = Tag.String("test").defaultValue("test2");
|
||||
var tag2 = Tag.String("test").defaultValue("test3");
|
||||
assertTrue(tag.shareValue(tag2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void differentType() {
|
||||
var tag = Tag.String("test");
|
||||
var tag2 = Tag.Integer("test");
|
||||
assertFalse(tag.shareValue(tag2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void list() {
|
||||
var tag = Tag.String("test").list();
|
||||
assertTrue(tag.shareValue(tag));
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void similarList() {
|
||||
// TODO make work
|
||||
var tag = Tag.String("test").list();
|
||||
var tag2 = Tag.String("test").list();
|
||||
assertTrue(tag.shareValue(tag2));
|
||||
}
|
||||
}
|
@ -236,6 +236,7 @@ public class TagPathTest {
|
||||
}
|
||||
}
|
||||
""", handler.asCompound());
|
||||
assertEquals(5, handler.getTag(tag.path("struct")));
|
||||
|
||||
handler.setTag(tag, 5);
|
||||
assertEqualsSNBT("""
|
||||
|
Loading…
Reference in New Issue
Block a user