diff --git a/jmh-benchmarks/src/jmh/java/net/minestom/jmh/palette/PaletteGetBenchmark.java b/jmh-benchmarks/src/jmh/java/net/minestom/jmh/palette/PaletteGetBenchmark.java index 27435eb81..0f42df0df 100644 --- a/jmh-benchmarks/src/jmh/java/net/minestom/jmh/palette/PaletteGetBenchmark.java +++ b/jmh-benchmarks/src/jmh/java/net/minestom/jmh/palette/PaletteGetBenchmark.java @@ -22,7 +22,7 @@ public class PaletteGetBenchmark { @Setup public void setup() { - palette = Palette.newPalette(dimension, 15, 4, 1); + palette = Palette.newPalette(dimension, 15, 4); AtomicInteger value = new AtomicInteger(); palette.setAll((x, y, z) -> value.getAndIncrement()); } diff --git a/src/main/java/net/minestom/server/instance/palette/AdaptivePalette.java b/src/main/java/net/minestom/server/instance/palette/AdaptivePalette.java index 8d98c632e..647f63f15 100644 --- a/src/main/java/net/minestom/server/instance/palette/AdaptivePalette.java +++ b/src/main/java/net/minestom/server/instance/palette/AdaptivePalette.java @@ -13,20 +13,16 @@ import java.util.function.IntUnaryOperator; */ final class AdaptivePalette implements Palette { final int dimension; - final int dimensionBitCount; final int maxBitsPerEntry; final int defaultBitsPerEntry; - final int bitsIncrement; SpecializedPalette palette; - AdaptivePalette(int dimension, int maxBitsPerEntry, int bitsPerEntry, int bitsIncrement) { - this.dimensionBitCount = validateDimension(dimension); - + AdaptivePalette(int dimension, int maxBitsPerEntry, int bitsPerEntry) { + validateDimension(dimension); this.dimension = dimension; this.maxBitsPerEntry = maxBitsPerEntry; this.defaultBitsPerEntry = bitsPerEntry; - this.bitsIncrement = bitsIncrement; this.palette = new FilledPalette(dimension, 0); } @@ -132,8 +128,9 @@ final class AdaptivePalette implements Palette { flexiblePalette.getAll((x, y, z, value) -> entries.add(value)); if (entries.size() == 1) { return new FilledPalette(dimension, entries.iterator().nextInt()); - } else { - final int bitsPerEntry = Math.max(4, MathUtils.bitsToRepresent(entries.size() - 1)); + } else if (flexiblePalette.bitsPerEntry() > defaultBitsPerEntry) { + final int bitsPerEntry = MathUtils.bitsToRepresent(entries.size() - 1); + assert bitsPerEntry < flexiblePalette.bitsPerEntry(); flexiblePalette.resize(bitsPerEntry); return flexiblePalette; } diff --git a/src/main/java/net/minestom/server/instance/palette/FlexiblePalette.java b/src/main/java/net/minestom/server/instance/palette/FlexiblePalette.java index 3fb9a937d..ba3d93b45 100644 --- a/src/main/java/net/minestom/server/instance/palette/FlexiblePalette.java +++ b/src/main/java/net/minestom/server/instance/palette/FlexiblePalette.java @@ -30,6 +30,7 @@ final class FlexiblePalette implements SpecializedPalette, Cloneable { // Specific to this palette type private final AdaptivePalette adaptivePalette; + private final int dimensionBitCount; private int bitsPerEntry; private boolean hasPalette; @@ -44,6 +45,7 @@ final class FlexiblePalette implements SpecializedPalette, Cloneable { FlexiblePalette(AdaptivePalette adaptivePalette, int bitsPerEntry) { this.adaptivePalette = adaptivePalette; + this.dimensionBitCount = (int) (Math.log(adaptivePalette.dimension()) / Math.log(2)); this.bitsPerEntry = bitsPerEntry; this.hasPalette = bitsPerEntry <= maxBitsPerEntry(); @@ -257,7 +259,7 @@ final class FlexiblePalette implements SpecializedPalette, Cloneable { final int size = maxSize(); final int dimensionMinus = dimension - 1; final int[] ids = hasPalette ? paletteToValueList.elements() : null; - final int dimensionBitCount = adaptivePalette.dimensionBitCount; + final int dimensionBitCount = this.dimensionBitCount; final int shiftedDimensionBitCount = dimensionBitCount << 1; for (int i = 0; i < values.length; i++) { final long value = values[i]; @@ -329,7 +331,7 @@ final class FlexiblePalette implements SpecializedPalette, Cloneable { final int lastPaletteIndex = this.lastPaletteIndex; if (lastPaletteIndex >= maxPaletteSize(bitsPerEntry)) { // Palette is full, must resize - resize(bitsPerEntry + adaptivePalette.bitsIncrement); + resize(bitsPerEntry + 1); return getPaletteIndex(value); } final int lookup = valueToPaletteMap.putIfAbsent(value, lastPaletteIndex); @@ -340,7 +342,7 @@ final class FlexiblePalette implements SpecializedPalette, Cloneable { } int getSectionIndex(int x, int y, int z) { - final int dimensionBitCount = adaptivePalette.dimensionBitCount; + final int dimensionBitCount = this.dimensionBitCount; return y << (dimensionBitCount << 1) | z << dimensionBitCount | x; } diff --git a/src/main/java/net/minestom/server/instance/palette/Palette.java b/src/main/java/net/minestom/server/instance/palette/Palette.java index 3e7465c97..40cfd29b0 100644 --- a/src/main/java/net/minestom/server/instance/palette/Palette.java +++ b/src/main/java/net/minestom/server/instance/palette/Palette.java @@ -12,15 +12,15 @@ import java.util.function.IntUnaryOperator; */ public interface Palette extends Writeable { static Palette blocks() { - return newPalette(16, 8, 6, 1); + return newPalette(16, 8, 4); } static Palette biomes() { - return newPalette(4, 2, 1, 1); + return newPalette(4, 3, 1); } - static Palette newPalette(int dimension, int maxBitsPerEntry, int bitsPerEntry, int bitIncrement) { - return new AdaptivePalette(dimension, maxBitsPerEntry, bitsPerEntry, bitIncrement); + static Palette newPalette(int dimension, int maxBitsPerEntry, int bitsPerEntry) { + return new AdaptivePalette(dimension, maxBitsPerEntry, bitsPerEntry); } int get(int x, int y, int z); diff --git a/src/test/java/net/minestom/server/instance/palette/PaletteTest.java b/src/test/java/net/minestom/server/instance/palette/PaletteTest.java index 7c17db3c9..a77944b92 100644 --- a/src/test/java/net/minestom/server/instance/palette/PaletteTest.java +++ b/src/test/java/net/minestom/server/instance/palette/PaletteTest.java @@ -71,7 +71,7 @@ public class PaletteTest { @Test public void resize() { - Palette palette = Palette.newPalette(16, 5, 2, 1); + Palette palette = Palette.newPalette(16, 5, 2); palette.set(0, 0, 0, 1); assertEquals(2, palette.bitsPerEntry()); palette.set(0, 0, 1, 2); @@ -252,7 +252,7 @@ public class PaletteTest { @Test public void replaceLoop() { - var palette = Palette.newPalette(2, 15, 4, 1); + var palette = Palette.newPalette(2, 15, 4); palette.setAll((x, y, z) -> x + y + z); final int dimension = palette.dimension(); for (int x = 0; x < dimension; x++) { @@ -266,21 +266,21 @@ public class PaletteTest { @Test public void dimension() { - assertThrows(Exception.class, () -> Palette.newPalette(-4, 5, 3, 1)); - assertThrows(Exception.class, () -> Palette.newPalette(0, 5, 3, 1)); - assertThrows(Exception.class, () -> Palette.newPalette(1, 5, 3, 1)); - assertDoesNotThrow(() -> Palette.newPalette(2, 5, 3, 1)); - assertThrows(Exception.class, () -> Palette.newPalette(3, 5, 3, 1)); - assertDoesNotThrow(() -> Palette.newPalette(4, 5, 3, 1)); - assertThrows(Exception.class, () -> Palette.newPalette(6, 5, 3, 1)); - assertDoesNotThrow(() -> Palette.newPalette(16, 5, 3, 1)); + assertThrows(Exception.class, () -> Palette.newPalette(-4, 5, 3)); + assertThrows(Exception.class, () -> Palette.newPalette(0, 5, 3)); + assertThrows(Exception.class, () -> Palette.newPalette(1, 5, 3)); + assertDoesNotThrow(() -> Palette.newPalette(2, 5, 3)); + assertThrows(Exception.class, () -> Palette.newPalette(3, 5, 3)); + assertDoesNotThrow(() -> Palette.newPalette(4, 5, 3)); + assertThrows(Exception.class, () -> Palette.newPalette(6, 5, 3)); + assertDoesNotThrow(() -> Palette.newPalette(16, 5, 3)); } private static List testPalettes() { return List.of( - Palette.newPalette(2, 5, 3, 1), - Palette.newPalette(4, 5, 3, 1), - Palette.newPalette(8, 5, 3, 1), - Palette.newPalette(16, 5, 3, 1)); + Palette.newPalette(2, 5, 3), + Palette.newPalette(4, 5, 3), + Palette.newPalette(8, 5, 3), + Palette.newPalette(16, 5, 3)); } }