improve ingest and saving perf

This commit is contained in:
mcrcortex
2025-07-19 11:44:40 +10:00
parent f590ad704e
commit 4a34b29b46
2 changed files with 39 additions and 12 deletions

View File

@@ -14,7 +14,7 @@ public class SaveLoadSystem3 {
private record SerializationCache(Long2ShortOpenHashMap lutMapCache, MemoryBuffer memoryBuffer) { private record SerializationCache(Long2ShortOpenHashMap lutMapCache, MemoryBuffer memoryBuffer) {
public SerializationCache() { public SerializationCache() {
this(new Long2ShortOpenHashMap(512), ThreadLocalMemoryBuffer.create(WorldSection.SECTION_VOLUME*2+WorldSection.SECTION_VOLUME*8+1024)); this(new Long2ShortOpenHashMap(1024), ThreadLocalMemoryBuffer.create(WorldSection.SECTION_VOLUME*2+WorldSection.SECTION_VOLUME*8+1024));
this.lutMapCache.defaultReturnValue((short) -1); this.lutMapCache.defaultReturnValue((short) -1);
} }
} }

View File

@@ -23,6 +23,7 @@ import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -36,9 +37,13 @@ public class Mapper {
public static final long UNKNOWN_MAPPING = -1; public static final long UNKNOWN_MAPPING = -1;
public static final long AIR = 0; public static final long AIR = 0;
private final Map<BlockState, StateEntry> block2stateEntry = new ConcurrentHashMap<>(2000,0.75f, 10); private final ReentrantLock blockLock = new ReentrantLock();
private final ConcurrentHashMap<BlockState, StateEntry> block2stateEntry = new ConcurrentHashMap<>(2000,0.75f, 10);
private final ObjectArrayList<StateEntry> blockId2stateEntry = new ObjectArrayList<>(); private final ObjectArrayList<StateEntry> blockId2stateEntry = new ObjectArrayList<>();
private final Map<String, BiomeEntry> biome2biomeEntry = new ConcurrentHashMap<>(2000,0.75f, 10);
private final ReentrantLock biomeLock = new ReentrantLock();
private final ConcurrentHashMap<String, BiomeEntry> biome2biomeEntry = new ConcurrentHashMap<>(2000,0.75f, 10);
private final ObjectArrayList<BiomeEntry> biomeId2biomeEntry = new ObjectArrayList<>(); private final ObjectArrayList<BiomeEntry> biomeId2biomeEntry = new ObjectArrayList<>();
private Consumer<StateEntry> newStateCallback; private Consumer<StateEntry> newStateCallback;
@@ -151,10 +156,18 @@ public class Mapper {
} }
private synchronized StateEntry registerNewBlockState(BlockState state) { private StateEntry registerNewBlockState(BlockState state) {
StateEntry entry = new StateEntry(this.blockId2stateEntry.size(), state); this.blockLock.lock();
//this.block2stateEntry.put(state, entry); var entry = this.block2stateEntry.get(state);
if (entry != null) {
this.blockLock.unlock();
return entry;
}
entry = new StateEntry(this.blockId2stateEntry.size(), state);
this.block2stateEntry.put(state, entry);
this.blockId2stateEntry.add(entry); this.blockId2stateEntry.add(entry);
this.blockLock.unlock();
byte[] serialized = entry.serialize(); byte[] serialized = entry.serialize();
ByteBuffer buffer = MemoryUtil.memAlloc(serialized.length); ByteBuffer buffer = MemoryUtil.memAlloc(serialized.length);
@@ -167,10 +180,17 @@ public class Mapper {
return entry; return entry;
} }
private synchronized BiomeEntry registerNewBiome(String biome) { private BiomeEntry registerNewBiome(String biome) {
BiomeEntry entry = new BiomeEntry(this.biomeId2biomeEntry.size(), biome); this.biomeLock.lock();
//this.biome2biomeEntry.put(biome, entry); var entry = this.biome2biomeEntry.get(biome);
if (entry != null) {
this.biomeLock.unlock();
return entry;
}
entry = new BiomeEntry(this.biomeId2biomeEntry.size(), biome);
this.biome2biomeEntry.put(biome, entry);
this.biomeId2biomeEntry.add(entry); this.biomeId2biomeEntry.add(entry);
this.biomeLock.unlock();
byte[] serialized = entry.serialize(); byte[] serialized = entry.serialize();
ByteBuffer buffer = MemoryUtil.memAlloc(serialized.length); ByteBuffer buffer = MemoryUtil.memAlloc(serialized.length);
@@ -199,7 +219,11 @@ public class Mapper {
if (state.isAir()) { if (state.isAir()) {
return 0; return 0;
} }
return this.block2stateEntry.computeIfAbsent(state, this::registerNewBlockState).id; var mapping = this.block2stateEntry.get(state);
if (mapping == null) {
mapping = this.registerNewBlockState(state);
}
return mapping.id;
} }
public int getBlockStateOpacity(long mappingId) { public int getBlockStateOpacity(long mappingId) {
@@ -210,10 +234,13 @@ public class Mapper {
return this.blockId2stateEntry.get(blockId).opacity; return this.blockId2stateEntry.get(blockId).opacity;
} }
//TODO: replace lambda with a class cached lambda ref (cause doing this:: still does a lambda allocation)
public int getIdForBiome(RegistryEntry<Biome> biome) { public int getIdForBiome(RegistryEntry<Biome> biome) {
String biomeId = biome.getKey().get().getValue().toString(); String biomeId = biome.getKey().get().getValue().toString();
return this.biome2biomeEntry.computeIfAbsent(biomeId, this::registerNewBiome).id; var entry = this.biome2biomeEntry.get(biomeId);
if (entry == null) {
entry = this.registerNewBiome(biomeId);
}
return entry.id;
} }
public static long composeMappingId(byte light, int blockId, int biomeId) { public static long composeMappingId(byte light, int blockId, int biomeId) {