Use a resizable list to store palette ids

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2021-11-06 10:27:05 +01:00
parent 11e26718b0
commit 86d9c20150

View File

@ -1,6 +1,7 @@
package net.minestom.server.instance.palette; package net.minestom.server.instance.palette;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Chunk;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
@ -31,9 +32,9 @@ final class PaletteImpl implements Palette {
private long[] values = new long[0]; private long[] values = new long[0];
// palette index = value // palette index = value
private int[] paletteToValueArray; private IntArrayList paletteToValueList;
// value = palette index // value = palette index
private Int2IntOpenHashMap valueToPaletteMap = new Int2IntOpenHashMap(); private Int2IntOpenHashMap valueToPaletteMap;
PaletteImpl(int size, int maxBitsPerEntry, int bitsPerEntry, int bitsIncrement) { PaletteImpl(int size, int maxBitsPerEntry, int bitsPerEntry, int bitsIncrement) {
this.size = size; this.size = size;
@ -45,8 +46,10 @@ final class PaletteImpl implements Palette {
this.valuesPerLong = Long.SIZE / bitsPerEntry; this.valuesPerLong = Long.SIZE / bitsPerEntry;
this.hasPalette = bitsPerEntry <= maxBitsPerEntry; this.hasPalette = bitsPerEntry <= maxBitsPerEntry;
this.paletteToValueArray = new int[1 << bitsPerEntry]; final int initialCapacity = maxPaletteSize(bitsPerEntry) / 4;
this.paletteToValueList = new IntArrayList(initialCapacity);
this.paletteToValueList.add(0);
this.valueToPaletteMap = new Int2IntOpenHashMap(initialCapacity);
this.valueToPaletteMap.put(0, 0); this.valueToPaletteMap.put(0, 0);
} }
@ -61,7 +64,7 @@ final class PaletteImpl implements Palette {
final int bitIndex = sectionIdentifier % valuesPerLong * bitsPerEntry; final int bitIndex = sectionIdentifier % valuesPerLong * bitsPerEntry;
final short value = (short) (values[index] >> bitIndex & MAGIC_MASKS[bitsPerEntry]); final short value = (short) (values[index] >> bitIndex & MAGIC_MASKS[bitsPerEntry]);
// Change to palette value and return // Change to palette value and return
return hasPalette ? paletteToValueArray[value] : value; return hasPalette ? paletteToValueList.getInt(value) : value;
} }
@Override @Override
@ -133,7 +136,7 @@ final class PaletteImpl implements Palette {
try { try {
PaletteImpl palette = (PaletteImpl) super.clone(); PaletteImpl palette = (PaletteImpl) super.clone();
palette.values = values.clone(); palette.values = values.clone();
palette.paletteToValueArray = paletteToValueArray.clone(); palette.paletteToValueList = paletteToValueList.clone();
palette.valueToPaletteMap = valueToPaletteMap.clone(); palette.valueToPaletteMap = valueToPaletteMap.clone();
palette.count = count; palette.count = count;
return palette; return palette;
@ -149,10 +152,9 @@ final class PaletteImpl implements Palette {
// Palette // Palette
if (bitsPerEntry < 9) { if (bitsPerEntry < 9) {
// Palette has to exist // Palette has to exist
final int paletteSize = lastPaletteIndex + 1; writer.writeVarInt(lastPaletteIndex);
writer.writeVarInt(paletteSize); for (int i = 0; i < lastPaletteIndex; i++) {
for (int i = 0; i < paletteSize; i++) { writer.writeVarInt(paletteToValueList.getInt(i));
writer.writeVarInt(paletteToValueArray[i]);
} }
} }
// Raw // Raw
@ -177,7 +179,7 @@ final class PaletteImpl implements Palette {
} }
} }
this.paletteToValueArray = palette.paletteToValueArray; this.paletteToValueList = palette.paletteToValueList;
this.lastPaletteIndex = palette.lastPaletteIndex; this.lastPaletteIndex = palette.lastPaletteIndex;
this.bitsPerEntry = palette.bitsPerEntry; this.bitsPerEntry = palette.bitsPerEntry;
@ -194,13 +196,13 @@ final class PaletteImpl implements Palette {
final int lookup = valueToPaletteMap.getOrDefault(value, (short) -1); final int lookup = valueToPaletteMap.getOrDefault(value, (short) -1);
if (lookup != -1) return lookup; if (lookup != -1) return lookup;
if (lastPaletteIndex >= paletteToValueArray.length) { if (lastPaletteIndex >= maxPaletteSize(bitsPerEntry)) {
// Palette is full, must resize // Palette is full, must resize
resize(bitsPerEntry + bitsIncrement); resize(bitsPerEntry + bitsIncrement);
if (!hasPalette) return value; if (!hasPalette) return value;
} }
final int paletteIndex = lastPaletteIndex++; final int paletteIndex = lastPaletteIndex++;
this.paletteToValueArray[paletteIndex] = value; this.paletteToValueList.add(value);
this.valueToPaletteMap.put(value, paletteIndex); this.valueToPaletteMap.put(value, paletteIndex);
return paletteIndex; return paletteIndex;
} }
@ -209,4 +211,8 @@ final class PaletteImpl implements Palette {
y = Math.floorMod(y, CHUNK_SECTION_SIZE); y = Math.floorMod(y, CHUNK_SECTION_SIZE);
return y << 8 | z << 4 | x; return y << 8 | z << 4 | x;
} }
static int maxPaletteSize(int bitsPerEntry) {
return 1 << bitsPerEntry;
}
} }