3
0
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:
Pablo Herrera 2023-08-14 02:40:10 +02:00 committet von GitHub
Ursprung 23f776a6ee
Commit e112f81ec8
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
2 geänderte Dateien mit 91 neuen und 15 gelöschten Zeilen

Datei anzeigen

@ -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;
}
}
} }

Datei anzeigen

@ -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;
} }
} }