Test for palette optimizations

This commit is contained in:
themode 2022-02-24 22:21:11 +01:00
parent 2c0b026e46
commit 7428176206
4 changed files with 90 additions and 9 deletions

View File

@ -1,5 +1,8 @@
package net.minestom.server.instance.palette;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull;
@ -15,7 +18,7 @@ final class AdaptivePalette implements Palette {
final int defaultBitsPerEntry;
final int bitsIncrement;
private SpecializedPalette palette;
SpecializedPalette palette;
AdaptivePalette(int dimension, int maxBitsPerEntry, int bitsPerEntry, int bitsIncrement) {
this.dimensionBitCount = validateDimension(dimension);
@ -121,11 +124,16 @@ final class AdaptivePalette implements Palette {
final int count = flexiblePalette.count();
if (count == 0) {
return (this.palette = new FilledPalette(dimension, 0));
} else if (count == flexiblePalette.maxSize()) {
var palette = flexiblePalette.paletteToValueList;
if (palette.size() == 2 && palette.getInt(0) == 0) {
// first element is air, second should be the value the palette is filled with
return (this.palette = new FilledPalette(dimension, palette.getInt(1)));
} else {
// Find all entries and compress the palette
IntSet entries = new IntOpenHashSet(flexiblePalette.paletteToValueList.size());
currentPalette.getAll((x, y, z, value) -> entries.add(value));
final int bitsPerEntry = MathUtils.bitsToRepresent(entries.size());
if (bitsPerEntry == 1) {
return (this.palette = new FilledPalette(dimension, entries.iterator().nextInt()));
} else {
flexiblePalette.resize(bitsPerEntry);
return flexiblePalette;
}
}
}

View File

@ -311,7 +311,7 @@ final class FlexiblePalette implements SpecializedPalette, Cloneable {
}
}
private void resize(int newBitsPerEntry) {
void resize(int newBitsPerEntry) {
FlexiblePalette palette = new FlexiblePalette(adaptivePalette, fixBitsPerEntry(newBitsPerEntry));
palette.lastPaletteIndex = lastPaletteIndex;
palette.paletteToValueList = paletteToValueList;

View File

@ -0,0 +1,74 @@
package net.minestom.server.instance.palette;
import net.minestom.server.utils.binary.BinaryWriter;
import org.junit.jupiter.api.Test;
import java.util.Random;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class PaletteOptimizationTest {
@Test
public void empty() {
var palette = createPalette();
paletteEquals(palette.palette, palette.optimizedPalette());
}
@Test
public void single() {
var palette = createPalette();
palette.set(0, 0, 0, 1);
paletteEquals(palette.palette, palette.optimizedPalette());
}
@Test
public void random() {
var random = new Random(12345);
var palette = createPalette();
palette.setAll((x, y, z) -> random.nextInt(256));
paletteEquals(palette.palette, palette.optimizedPalette());
palette.setAll((x, y, z) -> random.nextInt(2));
paletteEquals(palette.palette, palette.optimizedPalette());
}
@Test
public void manualFill() {
var palette = createPalette();
palette.setAll((x, y, z) -> 1);
paletteEquals(palette.palette, palette.optimizedPalette());
palette.setAll((x, y, z) -> 2);
paletteEquals(palette.palette, palette.optimizedPalette());
palette.setAll((x, y, z) -> 0);
paletteEquals(palette.palette, palette.optimizedPalette());
}
AdaptivePalette createPalette() {
return (AdaptivePalette) Palette.blocks();
}
void paletteEquals(Palette palette, Palette optimized) {
// Verify content
assertEquals(palette.dimension(), optimized.dimension());
for (int y = 0; y < palette.dimension(); y++) {
for (int z = 0; z < palette.dimension(); z++) {
for (int x = 0; x < palette.dimension(); x++) {
assertEquals(palette.get(x, y, z), optimized.get(x, y, z));
}
}
}
// Verify size
{
var writer = new BinaryWriter(4096);
palette.write(writer);
int length1 = writer.toByteArray().length;
writer = new BinaryWriter(4096);
optimized.write(writer);
int length2 = writer.toByteArray().length;
System.out.println("debug: " + Thread.currentThread().getStackTrace()[2].getMethodName() + " " + length1 + " " + length2);
assertTrue(length1 >= length2, "Optimized palette is bigger than the original one: " + length1 + " : " + length2);
}
}
}

View File

@ -1,8 +1,7 @@
package net.minestom.server.instance;
package net.minestom.server.instance.palette;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.instance.palette.Palette;
import org.junit.jupiter.api.Test;
import java.util.HashSet;