From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Mon, 21 Oct 2024 12:52:44 -0700 Subject: [PATCH] Revert "Custom table implementation for blockstate state lookups" This reverts commit 14a7e6521ba0ce6dc8ebf98a1ccce59a5ec6a194. TODO Replace via deleting the patch diff --git a/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java b/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java deleted file mode 100644 index 57d0cd3ad6f972e986c72a57f1a6e36003f190c2..0000000000000000000000000000000000000000 --- a/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java +++ /dev/null @@ -1,160 +0,0 @@ -package io.papermc.paper.util.table; - -import com.google.common.collect.Table; -import net.minecraft.world.level.block.state.StateHolder; -import net.minecraft.world.level.block.state.properties.Property; -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -public final class ZeroCollidingReferenceStateTable { - - // upper 32 bits: starting index - // lower 32 bits: bitset for contained ids - protected final long[] this_index_table; - protected final Comparable[] this_table; - protected final StateHolder this_state; - - protected long[] index_table; - protected StateHolder[][] value_table; - - public ZeroCollidingReferenceStateTable(final StateHolder state, final Map, Comparable> this_map) { - this.this_state = state; - this.this_index_table = this.create_table(this_map.keySet()); - - int max_id = -1; - for (final Property property : this_map.keySet()) { - final int id = lookup_vindex(property, this.this_index_table); - if (id > max_id) { - max_id = id; - } - } - - this.this_table = new Comparable[max_id + 1]; - for (final Map.Entry, Comparable> entry : this_map.entrySet()) { - this.this_table[lookup_vindex(entry.getKey(), this.this_index_table)] = entry.getValue(); - } - } - - public void loadInTable(final Table, Comparable, StateHolder> table, - final Map, Comparable> this_map) { - final Set> combined = new HashSet<>(table.rowKeySet()); - combined.addAll(this_map.keySet()); - - this.index_table = this.create_table(combined); - - int max_id = -1; - for (final Property property : combined) { - final int id = lookup_vindex(property, this.index_table); - if (id > max_id) { - max_id = id; - } - } - - this.value_table = new StateHolder[max_id + 1][]; - - final Map, Map, StateHolder>> map = table.rowMap(); - for (final Property property : map.keySet()) { - final Map, StateHolder> propertyMap = map.get(property); - - final int id = lookup_vindex(property, this.index_table); - final StateHolder[] states = this.value_table[id] = new StateHolder[property.getPossibleValues().size()]; - - for (final Map.Entry, StateHolder> entry : propertyMap.entrySet()) { - if (entry.getValue() == null) { - // TODO what - continue; - } - - states[((Property)property).getIdFor(entry.getKey())] = entry.getValue(); - } - } - - - for (final Map.Entry, Comparable> entry : this_map.entrySet()) { - final Property property = entry.getKey(); - final int index = lookup_vindex(property, this.index_table); - - if (this.value_table[index] == null) { - this.value_table[index] = new StateHolder[property.getPossibleValues().size()]; - } - - this.value_table[index][((Property)property).getIdFor(entry.getValue())] = this.this_state; - } - } - - - protected long[] create_table(final Collection> collection) { - int max_id = -1; - for (final Property property : collection) { - final int id = property.getId(); - if (id > max_id) { - max_id = id; - } - } - - final long[] ret = new long[((max_id + 1) + 31) >>> 5]; // ceil((max_id + 1) / 32) - - for (final Property property : collection) { - final int id = property.getId(); - - ret[id >>> 5] |= (1L << (id & 31)); - } - - int total = 0; - for (int i = 1, len = ret.length; i < len; ++i) { - ret[i] |= (long)(total += Long.bitCount(ret[i - 1] & 0xFFFFFFFFL)) << 32; - } - - return ret; - } - - public Comparable get(final Property state) { - final Comparable[] table = this.this_table; - final int index = lookup_vindex(state, this.this_index_table); - - if (index < 0 || index >= table.length) { - return null; - } - return table[index]; - } - - public StateHolder get(final Property property, final Comparable with) { - final int withId = ((Property)property).getIdFor(with); - if (withId < 0) { - return null; - } - - final int index = lookup_vindex(property, this.index_table); - final StateHolder[][] table = this.value_table; - if (index < 0 || index >= table.length) { - return null; - } - - final StateHolder[] values = table[index]; - - if (withId >= values.length) { - return null; - } - - return values[withId]; - } - - protected static int lookup_vindex(final Property property, final long[] index_table) { - final int id = property.getId(); - final long bitset_mask = (1L << (id & 31)); - final long lower_mask = bitset_mask - 1; - final int index = id >>> 5; - if (index >= index_table.length) { - return -1; - } - final long index_value = index_table[index]; - final long contains_check = ((index_value & bitset_mask) - 1) >> (Long.SIZE - 1); // -1L if doesn't contain - - // index = total bits set in lower table values (upper 32 bits of index_value) plus total bits set in lower indices below id - // contains_check is 0 if the bitset had id set, else it's -1: so index is unaffected if contains_check == 0, - // otherwise it comes out as -1. - return (int)(((index_value >>> 32) + Long.bitCount(index_value & lower_mask)) | contains_check); - } -} diff --git a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java index 45744d86e9582a93a0cec26009deea091080fbbe..daedcfd867ed6171fb61bdcbded417a11c8a5b0f 100644 --- a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java +++ b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java @@ -39,13 +39,11 @@ public abstract class StateHolder { private final Reference2ObjectArrayMap, Comparable> values; private Table, Comparable, S> neighbours; protected final MapCodec propertiesCodec; - protected final io.papermc.paper.util.table.ZeroCollidingReferenceStateTable optimisedTable; // Paper - optimise state lookup protected StateHolder(O owner, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { this.owner = owner; this.values = propertyMap; this.propertiesCodec = codec; - this.optimisedTable = new io.papermc.paper.util.table.ZeroCollidingReferenceStateTable(this, propertyMap); // Paper - optimise state lookup } public > S cycle(Property property) { @@ -86,11 +84,11 @@ public abstract class StateHolder { } public > boolean hasProperty(Property property) { - return this.optimisedTable.get(property) != null; // Paper - optimise state lookup + return this.values.containsKey(property); } public > T getValue(Property property) { - Comparable comparable = this.optimisedTable.get(property); // Paper - optimise state lookup + Comparable comparable = this.values.get(property); if (comparable == null) { throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner); } else { @@ -99,18 +97,24 @@ public abstract class StateHolder { } public > Optional getOptionalValue(Property property) { - Comparable comparable = this.optimisedTable.get(property); // Paper - optimise state lookup + Comparable comparable = this.values.get(property); return comparable == null ? Optional.empty() : Optional.of(property.getValueClass().cast(comparable)); } public , V extends T> S setValue(Property property, V value) { - // Paper start - optimise state lookup - final S ret = (S)this.optimisedTable.get(property, value); - if (ret == null) { - throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); + Comparable comparable = this.values.get(property); + if (comparable == null) { + throw new IllegalArgumentException("Cannot set property " + property + " as it does not exist in " + this.owner); + } else if (comparable.equals(value)) { + return (S)this; + } else { + S object = this.neighbours.get(property, value); + if (object == null) { + throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); + } else { + return object; + } } - return ret; - // Paper end - optimise state lookup } public , V extends T> S trySetValue(Property property, V value) { @@ -143,7 +147,7 @@ public abstract class StateHolder { } } - this.neighbours = (Table, Comparable, S>)(table.isEmpty() ? table : ArrayTable.create(table)); this.optimisedTable.loadInTable((Table)this.neighbours, this.values); // Paper - optimise state lookup + this.neighbours = (Table, Comparable, S>)(table.isEmpty() ? table : ArrayTable.create(table)); } } diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java index ff5fd91257c4554c523682009efe1db83f53fd5b..b63116b333b6e06494091a82588acfb639bddb71 100644 --- a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java +++ b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java @@ -7,13 +7,6 @@ import java.util.Optional; public class BooleanProperty extends Property { private final ImmutableSet values = ImmutableSet.of(true, false); - // Paper start - optimise iblockdata state lookup - @Override - public final int getIdFor(final Boolean value) { - return value.booleanValue() ? 1 : 0; - } - // Paper end - optimise iblockdata state lookup - protected BooleanProperty(String name) { super(name, Boolean.class); } diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java index 498c5abe0a9d024d77029719c621c1c8485791f3..3097298fe356df98967cf4bdeaaede69dfe8a441 100644 --- a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java +++ b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java @@ -15,15 +15,6 @@ public class EnumProperty & StringRepresentable> extends Prope private final ImmutableSet values; private final Map names = Maps.newHashMap(); - // Paper start - optimise iblockdata state lookup - private int[] idLookupTable; - - @Override - public final int getIdFor(final T value) { - return this.idLookupTable[value.ordinal()]; - } - // Paper end - optimise iblockdata state lookup - protected EnumProperty(String name, Class type, Collection values) { super(name, type); this.values = ImmutableSet.copyOf(values); @@ -36,14 +27,6 @@ public class EnumProperty & StringRepresentable> extends Prope this.names.put(string, enum_); } - // Paper start - optimise BlockState lookup - int id = 0; - this.idLookupTable = new int[type.getEnumConstants().length]; - java.util.Arrays.fill(this.idLookupTable, -1); - for (final T value : this.getPossibleValues()) { - this.idLookupTable[value.ordinal()] = id++; - } - // Paper end - optimise BlockState lookup } @Override diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java index 977504f2641d0133a572b0d5de85d058609343bb..3a850321a4bcc68058483b5fd53e829c425a68af 100644 --- a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java +++ b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java @@ -11,16 +11,6 @@ public class IntegerProperty extends Property { public final int min; public final int max; - // Paper start - optimise iblockdata state lookup - @Override - public final int getIdFor(final Integer value) { - final int val = value.intValue(); - final int ret = val - this.min; - - return ret | ((this.max - ret) >> 31); - } - // Paper end - optimise iblockdata state lookup - protected IntegerProperty(String name, int min, int max) { super(name, Integer.class); if (min < 0) { diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java index b9493e3762410aca8e683c32b5aef187c0bee082..9055f15af0cae55effa6942913a9d7edf3857e07 100644 --- a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java +++ b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java @@ -24,17 +24,6 @@ public abstract class Property> { ); private final Codec> valueCodec = this.codec.xmap(this::value, Property.Value::value); - // Paper start - optimise iblockdata state lookup - private static final java.util.concurrent.atomic.AtomicInteger ID_GENERATOR = new java.util.concurrent.atomic.AtomicInteger(); - private final int id = ID_GENERATOR.getAndIncrement(); - - public final int getId() { - return this.id; - } - - public abstract int getIdFor(final T value); - // Paper end - optimise state lookup - protected Property(String name, Class type) { this.clazz = type; this.name = name;