Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-11-03 14:50:30 +01:00
Optimize memory allocation for data palette (#3402)
Dieser Commit ist enthalten in:
Ursprung
23f776a6ee
Commit
e112f81ec8
@ -29,21 +29,24 @@ import it.unimi.dsi.fastutil.ints.IntList;
|
|||||||
|
|
||||||
public final class DataPaletteImpl implements DataPalette {
|
public final class DataPaletteImpl implements DataPalette {
|
||||||
|
|
||||||
|
private static final int DEFAULT_INITIAL_SIZE = 16;
|
||||||
|
|
||||||
private final IntList palette;
|
private final IntList palette;
|
||||||
private final Int2IntMap inversePalette;
|
private final Int2IntMap inversePalette;
|
||||||
private final int[] values;
|
|
||||||
private final int sizeBits;
|
private final int sizeBits;
|
||||||
|
private ChunkData values;
|
||||||
|
|
||||||
public DataPaletteImpl(final int valuesLength) {
|
public DataPaletteImpl(final int valuesLength) {
|
||||||
this(valuesLength, 8);
|
this(valuesLength, DEFAULT_INITIAL_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataPaletteImpl(final int valuesLength, final int expectedPaletteLength) {
|
public DataPaletteImpl(final int valuesLength, final int initialSize) {
|
||||||
this.values = new int[valuesLength];
|
values = new EmptyChunkData(valuesLength);
|
||||||
sizeBits = Integer.numberOfTrailingZeros(valuesLength) / 3;
|
sizeBits = Integer.numberOfTrailingZeros(valuesLength) / 3;
|
||||||
// Pre-size the palette array/map
|
// Pre-size the palette array/map
|
||||||
palette = new IntArrayList(expectedPaletteLength);
|
palette = new IntArrayList(initialSize);
|
||||||
inversePalette = new Int2IntOpenHashMap(expectedPaletteLength);
|
// To get an initial table size of initialSize, need to scale it down by load factor.
|
||||||
|
inversePalette = new Int2IntOpenHashMap((int) (initialSize * Int2IntOpenHashMap.DEFAULT_LOAD_FACTOR));
|
||||||
inversePalette.defaultReturnValue(-1);
|
inversePalette.defaultReturnValue(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +57,7 @@ public final class DataPaletteImpl implements DataPalette {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int idAt(final int sectionCoordinate) {
|
public int idAt(final int sectionCoordinate) {
|
||||||
final int index = values[sectionCoordinate];
|
final int index = values.get(sectionCoordinate);
|
||||||
return palette.getInt(index);
|
return palette.getInt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,17 +70,17 @@ public final class DataPaletteImpl implements DataPalette {
|
|||||||
inversePalette.put(id, index);
|
inversePalette.put(id, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
values[sectionCoordinate] = index;
|
values.set(sectionCoordinate, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int paletteIndexAt(final int packedCoordinate) {
|
public int paletteIndexAt(final int packedCoordinate) {
|
||||||
return values[packedCoordinate];
|
return values.get(packedCoordinate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPaletteIndexAt(final int sectionCoordinate, final int index) {
|
public void setPaletteIndexAt(final int sectionCoordinate, final int index) {
|
||||||
values[sectionCoordinate] = index;
|
values.set(sectionCoordinate, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -131,4 +134,77 @@ public final class DataPaletteImpl implements DataPalette {
|
|||||||
palette.clear();
|
palette.clear();
|
||||||
inversePalette.clear();
|
inversePalette.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ChunkData {
|
||||||
|
int get(int idx);
|
||||||
|
void set(int idx, int val);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class EmptyChunkData implements ChunkData {
|
||||||
|
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
public EmptyChunkData(int size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int get(int idx) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(int idx, int val) {
|
||||||
|
if (val != 0) {
|
||||||
|
values = new ByteChunkData(size);
|
||||||
|
values.set(idx, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ByteChunkData implements ChunkData {
|
||||||
|
private final byte[] data;
|
||||||
|
|
||||||
|
public ByteChunkData(int size) {
|
||||||
|
this.data = new byte[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int get(int idx) {
|
||||||
|
return data[idx] & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(int idx, int val) {
|
||||||
|
// Overflowed size of byte (over 256 different materials), go up to short
|
||||||
|
if (val > 0xFF) {
|
||||||
|
values = new ShortChunkData(data);
|
||||||
|
values.set(idx, val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data[idx] = (byte) val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ShortChunkData implements ChunkData {
|
||||||
|
private final short[] data;
|
||||||
|
|
||||||
|
public ShortChunkData(byte[] data) {
|
||||||
|
this.data = new short[data.length];
|
||||||
|
for (int i = 0; i < data.length; i++) {
|
||||||
|
this.data[i] = (short) (data[i] & 0xFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int get(int idx) {
|
||||||
|
return data[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(int idx, int val) {
|
||||||
|
data[idx] = (short) val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ public class BlockConnectionStorage implements StorableObject {
|
|||||||
private final Queue<Position> modified = EvictingQueue.create(5);
|
private final Queue<Position> modified = EvictingQueue.create(5);
|
||||||
|
|
||||||
// Cache to retrieve section quicker
|
// Cache to retrieve section quicker
|
||||||
private Long lastIndex;
|
private long lastIndex = -1;
|
||||||
private SectionData lastSection;
|
private SectionData lastSection;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -114,7 +114,7 @@ public class BlockConnectionStorage implements StorableObject {
|
|||||||
public void clear() {
|
public void clear() {
|
||||||
blockStorage.clear();
|
blockStorage.clear();
|
||||||
lastSection = null;
|
lastSection = null;
|
||||||
lastIndex = null;
|
lastIndex = -1;
|
||||||
modified.clear();
|
modified.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ public class BlockConnectionStorage implements StorableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private @Nullable SectionData getSection(long index) {
|
private @Nullable SectionData getSection(long index) {
|
||||||
if (lastIndex != null && lastIndex == index) {
|
if (lastIndex == index) {
|
||||||
return lastSection;
|
return lastSection;
|
||||||
}
|
}
|
||||||
lastIndex = index;
|
lastIndex = index;
|
||||||
@ -138,8 +138,8 @@ public class BlockConnectionStorage implements StorableObject {
|
|||||||
|
|
||||||
private void removeSection(long index) {
|
private void removeSection(long index) {
|
||||||
blockStorage.remove(index);
|
blockStorage.remove(index);
|
||||||
if (lastIndex != null && lastIndex == index) {
|
if (lastIndex == index) {
|
||||||
lastIndex = null;
|
lastIndex = -1;
|
||||||
lastSection = null;
|
lastSection = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren