Cheaper cave biome resolution

- carving root entries cached per world Y in arrays instead of a boxed-key map
- semantic cave capture skips re-adding the key it added last
This commit is contained in:
Brian Neumann-Fopiano committed 2026-09-28 13:43:39 -04:00
1 parent 2fef055e5c
commit c00dfbddce
3 files changed
+48 -15

No files matched your search

@@ -14,7 +14,7 @@ import art.arcane.volmlib.util.noise.CNG;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.Arrays;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -81,8 +81,9 @@ public final class IrisDimensionCarvingResolver {
} }
private static IrisDimensionCarvingEntry resolveBoundRootEntry(Engine engine, int worldY, IrisData data, State resolvedState) { private static IrisDimensionCarvingEntry resolveBoundRootEntry(Engine engine, int worldY, IrisData data, State resolvedState) {
if (resolvedState.rootEntriesByWorldY.containsKey(worldY)) { int slot = resolvedState.rootSlot(worldY);
return resolvedState.rootEntriesByWorldY.get(worldY); if (slot >= 0) {
return resolvedState.roots[slot];
} }
return selectBoundRootEntry(engine.getDimension(), worldY, data, resolvedState); return selectBoundRootEntry(engine.getDimension(), worldY, data, resolvedState);
@@ -91,7 +92,7 @@ public final class IrisDimensionCarvingResolver {
private static IrisDimensionCarvingEntry selectBoundRootEntry(IrisDimension dimension, int worldY, IrisData data, State resolvedState) { private static IrisDimensionCarvingEntry selectBoundRootEntry(IrisDimension dimension, int worldY, IrisData data, State resolvedState) {
List<IrisDimensionCarvingEntry> entries = dimension.getCarving(); List<IrisDimensionCarvingEntry> entries = dimension.getCarving();
if (entries == null || entries.isEmpty()) { if (entries == null || entries.isEmpty()) {
resolvedState.rootEntriesByWorldY.put(worldY, null); resolvedState.rememberRoot(worldY, null);
return null; return null;
} }
@@ -104,7 +105,7 @@ public final class IrisDimensionCarvingResolver {
resolved = entry; resolved = entry;
} }
resolvedState.rootEntriesByWorldY.put(worldY, resolved); resolvedState.rememberRoot(worldY, resolved);
return resolved; return resolved;
} }
@@ -324,8 +325,9 @@ public final class IrisDimensionCarvingResolver {
} }
public IrisBiome resolveBiome(int worldX, int worldY, int worldZ) { public IrisBiome resolveBiome(int worldX, int worldY, int worldZ) {
IrisDimensionCarvingEntry root = state.rootEntriesByWorldY.containsKey(worldY) int slot = state.rootSlot(worldY);
? state.rootEntriesByWorldY.get(worldY) IrisDimensionCarvingEntry root = slot >= 0
? state.roots[slot]
: selectBoundRootEntry(dimension, worldY, data, state); : selectBoundRootEntry(dimension, worldY, data, state);
if (root == null) { if (root == null) {
return null; return null;
@@ -336,7 +338,11 @@ public final class IrisDimensionCarvingResolver {
} }
public static final class State { public static final class State {
private final Map<Integer, IrisDimensionCarvingEntry> rootEntriesByWorldY = new HashMap<>(); private static final int ROOT_SLOTS = 512;
private int[] rootWorldYs;
private IrisDimensionCarvingEntry[] roots;
private boolean[] rootsKnown;
private final Map<IrisDimensionCarvingEntry, IrisRaritySelection<CarvingChoice>> selectionPlans = new IdentityHashMap<>(); private final Map<IrisDimensionCarvingEntry, IrisRaritySelection<CarvingChoice>> selectionPlans = new IdentityHashMap<>();
private final Map<IrisDimensionCarvingEntry, IrisBiome> biomeCache = new IdentityHashMap<>(); private final Map<IrisDimensionCarvingEntry, IrisBiome> biomeCache = new IdentityHashMap<>();
private WeakReference<Engine> engineIdentity; private WeakReference<Engine> engineIdentity;
@@ -357,7 +363,10 @@ public final class IrisDimensionCarvingResolver {
engineIdentity = new WeakReference<>(engine); engineIdentity = new WeakReference<>(engine);
dimensionIdentity = new WeakReference<>(dimension); dimensionIdentity = new WeakReference<>(dimension);
dataIdentity = new WeakReference<>(data); dataIdentity = new WeakReference<>(data);
rootEntriesByWorldY.clear(); if (rootsKnown != null) {
Arrays.fill(rootsKnown, false);
Arrays.fill(roots, null);
}
selectionPlans.clear(); selectionPlans.clear();
biomeCache.clear(); biomeCache.clear();
entryIndex = null; entryIndex = null;
@@ -366,6 +375,23 @@ public final class IrisDimensionCarvingResolver {
return data; return data;
} }
private int rootSlot(int worldY) {
int slot = worldY & (ROOT_SLOTS - 1);
return rootsKnown != null && rootsKnown[slot] && rootWorldYs[slot] == worldY ? slot : -1;
}
private void rememberRoot(int worldY, IrisDimensionCarvingEntry root) {
if (rootsKnown == null) {
rootWorldYs = new int[ROOT_SLOTS];
roots = new IrisDimensionCarvingEntry[ROOT_SLOTS];
rootsKnown = new boolean[ROOT_SLOTS];
}
int slot = worldY & (ROOT_SLOTS - 1);
rootWorldYs[slot] = worldY;
roots[slot] = root;
rootsKnown[slot] = true;
}
private static boolean references(WeakReference<?> identity, Object value) { private static boolean references(WeakReference<?> identity, Object value) {
return identity != null && identity.get() == value; return identity != null && identity.get() == value;
} }
@@ -227,12 +227,12 @@ public final class GenerationSemanticCapture {
} }
resolvedCaves.set(position); resolvedCaves.set(position);
if (explicitBiomeKey != null && !explicitBiomeKey.isBlank()) { if (explicitBiomeKey != null && !explicitBiomeKey.isBlank()) {
semantics.addCaveBiome(explicitBiomeKey); caveBiomes.add(semantics, explicitBiomeKey);
return; return;
} }
IrisBiome caveBiome = caveBiomes.resolve(blockX, y, blockZ); IrisBiome caveBiome = caveBiomes.resolve(blockX, y, blockZ);
if (caveBiome != null && caveBiome.getLoadKey() != null) { if (caveBiome != null && caveBiome.getLoadKey() != null) {
semantics.addCaveBiome(caveBiome.getLoadKey()); caveBiomes.add(semantics, caveBiome.getLoadKey());
} }
} }
@@ -280,6 +280,7 @@ public final class GenerationSemanticCapture {
private final IrisDimensionCarvingResolver.State fallbackState = new IrisDimensionCarvingResolver.State(); private final IrisDimensionCarvingResolver.State fallbackState = new IrisDimensionCarvingResolver.State();
private IrisDimensionCarvingResolver.Snapshot snapshot; private IrisDimensionCarvingResolver.Snapshot snapshot;
private int minimumY; private int minimumY;
private String lastKey;
private CaveBiomes(Engine engine, boolean scoped) { private CaveBiomes(Engine engine, boolean scoped) {
this.engine = engine; this.engine = engine;
@@ -290,6 +291,13 @@ public final class GenerationSemanticCapture {
: null; : null;
} }
private void add(ChunkGenerationSemantics.Builder semantics, String key) {
if (key != lastKey) {
semantics.addCaveBiome(key);
lastKey = key;
}
}
private IrisBiome resolve(int x, int y, int z) { private IrisBiome resolve(int x, int y, int z) {
if (!scoped) { if (!scoped) {
return engine.getCaveBiome(x, y, z); return engine.getCaveBiome(x, y, z);
@@ -494,12 +494,11 @@ public class IrisDimensionCarvingResolverParityTest {
assertSame(fixture.entry(), IrisDimensionCarvingResolver.resolveRootEntry( assertSame(fixture.entry(), IrisDimensionCarvingResolver.resolveRootEntry(
fixture.engine(), 80, state)); fixture.engine(), 80, state));
Field rootEntriesField = IrisDimensionCarvingResolver.State.class Field rootsField = IrisDimensionCarvingResolver.State.class.getDeclaredField("roots");
.getDeclaredField("rootEntriesByWorldY"); rootsField.setAccessible(true);
rootEntriesField.setAccessible(true);
System.gc(); System.gc();
assertSame(fixture.entry(), ((Map<?, ?>) rootEntriesField.get(state)).get(80)); assertSame(fixture.entry(), ((IrisDimensionCarvingEntry[]) rootsField.get(state))[80]);
} }
private RetainedFixture createRetainedFixture() { private RetainedFixture createRetainedFixture() {