Parallax Feature Performance Caching

This commit is contained in:
Daniel Mills 2021-07-17 00:33:32 -04:00
parent 1496d0e482
commit df9114d7b0
4 changed files with 74 additions and 28 deletions

View File

@ -18,8 +18,13 @@
package com.volmit.iris.engine;
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineParallaxManager;
import com.volmit.iris.engine.object.IrisFeaturePositional;
import com.volmit.iris.engine.stream.utility.CachedStream2D;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.scheduling.IrisLock;
import lombok.Getter;
public class IrisEngineParallax implements EngineParallaxManager {
@ -29,6 +34,16 @@ public class IrisEngineParallax implements EngineParallaxManager {
@Getter
private final int parallaxSize;
@Getter
private final IrisLock featureLock = new IrisLock("Feature");
@Getter
private final ConcurrentLinkedHashMap<Long, KList<IrisFeaturePositional>> featureCache = new ConcurrentLinkedHashMap.Builder<Long, KList<IrisFeaturePositional>>()
.initialCapacity(1024)
.maximumWeightedCapacity(1024)
.concurrencyLevel(32)
.build();
public IrisEngineParallax(Engine engine) {
this.engine = engine;
parallaxSize = computeParallaxSize();

View File

@ -20,7 +20,7 @@ package com.volmit.iris.engine.framework;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisDataManager;
import com.volmit.iris.engine.actuator.IrisTerrainActuator;
import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator;
import com.volmit.iris.engine.data.DataProvider;
import com.volmit.iris.engine.hunk.Hunk;
import com.volmit.iris.engine.object.IrisBiome;
@ -158,7 +158,7 @@ public interface EngineCompound extends Listener, Hotloadable, DataProvider {
Engine e = getEngine(i);
if (e.getDimension().isBedrock()) {
int m = ((IrisTerrainActuator) e.getFramework().getTerrainActuator()).getLastBedrock();
int m = ((IrisTerrainNormalActuator) e.getFramework().getTerrainActuator()).getLastBedrock();
if (f > m) {
f = m;

View File

@ -18,6 +18,7 @@
package com.volmit.iris.engine.framework;
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisDataManager;
import com.volmit.iris.engine.IrisComplex;
@ -40,6 +41,7 @@ import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.function.Consumer4;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.scheduling.IrisLock;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import org.bukkit.Chunk;
@ -192,41 +194,69 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
}
}
ConcurrentLinkedHashMap<Long, KList<IrisFeaturePositional>> getFeatureCache();
IrisLock getFeatureLock();
default void forEachFeature(double x, double z, Consumer<IrisFeaturePositional> f) {
for (IrisFeaturePositional i : getEngine().getDimension().getSpecificFeatures()) {
if (i.shouldFilter(x, z)) {
f.accept(i);
long key = Cache.key(((int)x)>>4, ((int)z) >> 4);
for(IrisFeaturePositional ipf : getFeatureCache().compute(key, (ke, v) -> {
if(v != null)
{
return v;
}
}
int s = (int) Math.ceil(getParallaxSize() / 2D);
int i, j;
int cx = (int) x >> 4;
int cz = (int) z >> 4;
getFeatureLock().lock();
KList<IrisFeaturePositional> pos = new KList<>();
for (i = -s; i <= s; i++) {
for (j = -s; j <= s; j++) {
ParallaxChunkMeta m = getParallaxAccess().getMetaR(i + cx, j + cz);
try {
synchronized (m.getFeatures()) {
for (IrisFeaturePositional k : m.getFeatures()) {
if (k.shouldFilter(x, z)) {
f.accept(k);
}
}
}
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
Iris.warn("Failed to read positional features in chunk " + (i + cx) + " " + (j + cz) + "(" + e.getClass().getSimpleName() + ")");
for (IrisFeaturePositional i : getEngine().getDimension().getSpecificFeatures()) {
if (i.shouldFilter(x, z)) {
pos.add(i);
}
}
int s = (int) Math.ceil(getParallaxSize() / 2D);
int i, j;
int cx = (int) x >> 4;
int cz = (int) z >> 4;
for (i = -s; i <= s; i++) {
for (j = -s; j <= s; j++) {
ParallaxChunkMeta m = getParallaxAccess().getMetaR(i + cx, j + cz);
try {
synchronized (m.getFeatures())
{
for (IrisFeaturePositional k : m.getFeatures()) {
if (k.shouldFilter(x, z)) {
pos.add(k);
}
}
}
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
Iris.warn("Failed to read positional features in chunk " + (i + cx) + " " + (j + cz) + "(" + e.getClass().getSimpleName() + ")");
}
}
}
getFeatureLock().unlock();
return pos;
}))
{
f.accept(ipf);
}
}
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
default void generateParallaxArea(int x, int z) {
if(!getEngine().getDimension().isPlaceObjects())
{
return;
}
try {
PrecisionStopwatch p = PrecisionStopwatch.start();

View File

@ -22,6 +22,7 @@ import com.google.gson.Gson;
import com.volmit.iris.engine.hunk.io.HunkIOAdapter;
import com.volmit.iris.engine.hunk.io.PaletteHunkIOAdapter;
import com.volmit.iris.engine.object.IrisFeaturePositional;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.oldnbt.CompoundTag;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -56,9 +57,9 @@ public class ParallaxChunkMeta {
private int maxObject = -1;
private int minObject = -1;
private int count;
private CopyOnWriteArrayList<IrisFeaturePositional> features;
private KList<IrisFeaturePositional> features;
public ParallaxChunkMeta() {
this(false, false, false, false, false, false, -1, -1, 0, new CopyOnWriteArrayList<>());
this(false, false, false, false, false, false, -1, -1, 0, new KList<>());
}
}