mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-04 07:28:19 +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);
|
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) {
|
public static @NotNull Tag<Byte> Byte(@NotNull String key) {
|
||||||
return tag(key, NBTByte::getValue, NBT::Byte);
|
return tag(key, NBTByte::getValue, NBT::Byte);
|
||||||
}
|
}
|
||||||
|
@ -172,6 +172,12 @@ final class TagHandlerImpl implements TagHandler {
|
|||||||
this.tag = tag;
|
this.tag = tag;
|
||||||
this.value = value;
|
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 {
|
private record Cache(Entry<?>[] entries, NBTCompound compound) implements TagReadable {
|
||||||
@ -196,6 +202,10 @@ final class TagHandlerImpl implements TagHandler {
|
|||||||
}
|
}
|
||||||
if (entry.value instanceof TagHandlerImpl handler) {
|
if (entry.value instanceof TagHandlerImpl handler) {
|
||||||
entries = handler.entries;
|
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)
|
if (value instanceof TagHandlerImpl)
|
||||||
throw new IllegalStateException("Cannot read path-able tag " + tag.getKey());
|
throw new IllegalStateException("Cannot read path-able tag " + tag.getKey());
|
||||||
final Tag entryTag = entry.tag;
|
final Tag entryTag = entry.tag;
|
||||||
if (entryTag == tag) {
|
if (entryTag.shareValue(tag)) {
|
||||||
// Tag is the same, return the value
|
// Tag is the same, return the value
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return (T) value;
|
return (T) value;
|
||||||
}
|
}
|
||||||
// Value must be parsed from nbt if the tag is different
|
// Value must be parsed from nbt if the tag is different
|
||||||
NBT nbt = entry.nbt;
|
final NBT nbt = entry.updatedNbt();
|
||||||
if (nbt == null) entry.nbt = nbt = (NBT) entryTag.writeFunction.apply(value);
|
|
||||||
try {
|
try {
|
||||||
return tag.readFunction.apply(nbt);
|
return tag.readFunction.apply(nbt);
|
||||||
} catch (ClassCastException e) {
|
} 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());
|
""", handler.asCompound());
|
||||||
|
assertEquals(5, handler.getTag(tag.path("struct")));
|
||||||
|
|
||||||
handler.setTag(tag, 5);
|
handler.setTag(tag, 5);
|
||||||
assertEqualsSNBT("""
|
assertEqualsSNBT("""
|
||||||
|
Loading…
Reference in New Issue
Block a user