mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-29 12:09:07 +00:00
Faster caching
This commit is contained in:
@@ -85,7 +85,7 @@ public abstract class ContextualTerrainProvider implements TerrainProvider, List
|
||||
tickLatch = new ChronoLatch(650);
|
||||
perSecond = new ChronoLatch(1000);
|
||||
hlast = M.ms();
|
||||
cache = new AtomicMulticache();
|
||||
cache = new AtomicMulticache((IrisTerrainProvider) this);
|
||||
CNG.creates = 0;
|
||||
generated = 0;
|
||||
ticks = 0;
|
||||
|
||||
@@ -249,7 +249,7 @@ public class IrisTerrainProvider extends SkyTerrainProvider implements IrisConte
|
||||
int iz = (int) z;
|
||||
double height = getTerrainHeight(ix, iz);
|
||||
IrisRegion region = sampleRegion(ix, iz);
|
||||
IrisBiome biome = sampleTrueBiome(ix, iz, height);
|
||||
IrisBiome biome = sampleTrueBiome(ix, iz);
|
||||
|
||||
if(biome.getCachedColor() != null)
|
||||
{
|
||||
@@ -276,7 +276,7 @@ public class IrisTerrainProvider extends SkyTerrainProvider implements IrisConte
|
||||
int iz = (int) z;
|
||||
double height = getTerrainHeight(ix, iz);
|
||||
IrisRegion region = sampleRegion(ix, iz);
|
||||
IrisBiome biome = sampleTrueBiome(ix, iz, height);
|
||||
IrisBiome biome = sampleTrueBiome(ix, iz);
|
||||
hb = biome;
|
||||
hr = region;
|
||||
return biome.getName() + " (" + Form.capitalizeWords(biome.getInferredType().name().toLowerCase().replaceAll("\\Q_\\E", " ") + ") in " + region.getName() + "\nY: " + (int) height);
|
||||
|
||||
@@ -65,7 +65,6 @@ public abstract class ParallelTerrainProvider extends DimensionalTerrainProvider
|
||||
|
||||
protected void onGenerate(RNG random, int x, int z, TerrainChunk terrain)
|
||||
{
|
||||
getCache().targetChunk(x, z);
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
AtomicSliverMap map = new AtomicSliverMap();
|
||||
HeightMap height = new HeightMap();
|
||||
|
||||
@@ -84,20 +84,10 @@ public abstract class TopographicTerrainProvider extends ParallelTerrainProvider
|
||||
{
|
||||
if(ignoreFluid)
|
||||
{
|
||||
return getCache().getCarvedHeightIgnoreWater(x, z, () ->
|
||||
{
|
||||
int h = (int) Math.round(getTerrainHeight(x, z));
|
||||
h = getGlCarve().getSurfaceCarve(x, h, z);
|
||||
return h;
|
||||
});
|
||||
return getCache().getCarvedHeightIgnoreWater(x, z);
|
||||
}
|
||||
|
||||
return getCache().getCarvedHeightIgnoreWater(x, z, () ->
|
||||
{
|
||||
int h = (int) Math.round(getTerrainWaterHeight(x, z));
|
||||
h = getGlCarve().getSurfaceCarve(x, h, z);
|
||||
return h;
|
||||
});
|
||||
return getCache().getCarvedHeight(x, z);
|
||||
}
|
||||
|
||||
public int getCarvedHeight(int x, int z)
|
||||
@@ -140,7 +130,7 @@ public abstract class TopographicTerrainProvider extends ParallelTerrainProvider
|
||||
int height = (int) Math.round(noise);
|
||||
boolean carvable = getGlCarve().couldCarveBelow(rx, height, rz);
|
||||
IrisRegion region = sampleRegion(rx, rz);
|
||||
IrisBiome biome = sampleTrueBiome(rx, rz, noise);
|
||||
IrisBiome biome = sampleTrueBiome(rx, rz);
|
||||
IrisBiome carveBiome = null;
|
||||
Biome onlyBiome = Iris.biome3d ? null : biome.getGroundBiome(getMasterRandom(), rz, getDimension().getFluidHeight(), rx);
|
||||
|
||||
@@ -582,20 +572,21 @@ public abstract class TopographicTerrainProvider extends ParallelTerrainProvider
|
||||
|
||||
}
|
||||
|
||||
private double getNoiseHeight(int rx, int rz)
|
||||
public double getNoiseHeight(int rx, int rz)
|
||||
{
|
||||
double h = getBiomeHeight(rx, rz);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
public IrisBiome sampleTrueBiomeBase(int x, int z, int height)
|
||||
public IrisBiome sampleTrueBiomeBase(int x, int z)
|
||||
{
|
||||
if(!getDimension().getFocus().equals(""))
|
||||
{
|
||||
return focus();
|
||||
}
|
||||
|
||||
int height = (int) Math.round(getTerrainHeight(x, z));
|
||||
double wx = getModifiedX(x, z);
|
||||
double wz = getModifiedZ(x, z);
|
||||
IrisRegion region = sampleRegion(x, z);
|
||||
@@ -671,29 +662,19 @@ public abstract class TopographicTerrainProvider extends ParallelTerrainProvider
|
||||
return sampleTrueBiome(x, z);
|
||||
}
|
||||
|
||||
public IrisBiome sampleTrueBiome(int x, int z)
|
||||
{
|
||||
return sampleTrueBiome(x, z, getTerrainHeight(x, z));
|
||||
}
|
||||
|
||||
public IrisRegion sampleRegion(int x, int z)
|
||||
{
|
||||
return getCache().getRegion(x, z, () ->
|
||||
{
|
||||
double wx = getModifiedX(x, z);
|
||||
double wz = getModifiedZ(x, z);
|
||||
return glBiome.getRegion(wx, wz);
|
||||
});
|
||||
return getCache().getRegion(x, z);
|
||||
}
|
||||
|
||||
public IrisBiome sampleTrueBiome(int x, int z, double noise)
|
||||
public IrisBiome sampleTrueBiome(int x, int z)
|
||||
{
|
||||
if(!getDimension().getFocus().equals(""))
|
||||
{
|
||||
return focus();
|
||||
}
|
||||
|
||||
return getCache().getBiome(x, z, () -> sampleTrueBiomeBase(x, z, (int) Math.round(noise)));
|
||||
return getCache().getBiome(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -724,7 +705,7 @@ public abstract class TopographicTerrainProvider extends ParallelTerrainProvider
|
||||
|
||||
public double getTerrainHeight(int x, int z)
|
||||
{
|
||||
return getCache().getHeight(x, z, () -> getNoiseHeight(x, z) + getFluidHeight());
|
||||
return getCache().getHeight(x, z);
|
||||
}
|
||||
|
||||
public double getTerrainWaterHeight(int x, int z)
|
||||
@@ -885,47 +866,49 @@ public abstract class TopographicTerrainProvider extends ParallelTerrainProvider
|
||||
|
||||
Iris.info("Loaded " + generators.size() + " Generators");
|
||||
}
|
||||
|
||||
public IrisBiome computeRawBiome(int x, int z)
|
||||
{
|
||||
if(!getDimension().getFocus().equals(""))
|
||||
{
|
||||
IrisBiome biome = loadBiome(getDimension().getFocus());
|
||||
|
||||
for(String i : getDimension().getRegions())
|
||||
{
|
||||
IrisRegion reg = loadRegion(i);
|
||||
|
||||
if(reg.getLandBiomes().contains(biome.getLoadKey()))
|
||||
{
|
||||
biome.setInferredType(InferredType.LAND);
|
||||
break;
|
||||
}
|
||||
|
||||
if(reg.getSeaBiomes().contains(biome.getLoadKey()))
|
||||
{
|
||||
biome.setInferredType(InferredType.SEA);
|
||||
break;
|
||||
}
|
||||
|
||||
if(reg.getShoreBiomes().contains(biome.getLoadKey()))
|
||||
{
|
||||
biome.setInferredType(InferredType.SHORE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return biome;
|
||||
}
|
||||
|
||||
double wx = getModifiedX(x, z);
|
||||
double wz = getModifiedZ(x, z);
|
||||
IrisRegion region = glBiome.getRegion(wx, wz);
|
||||
IrisBiome res = glBiome.generateRegionData(wx, wz, x, z, region);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public IrisBiome sampleBiome(int x, int z)
|
||||
{
|
||||
return getCache().getRawBiome(x, z, () ->
|
||||
{
|
||||
if(!getDimension().getFocus().equals(""))
|
||||
{
|
||||
IrisBiome biome = loadBiome(getDimension().getFocus());
|
||||
|
||||
for(String i : getDimension().getRegions())
|
||||
{
|
||||
IrisRegion reg = loadRegion(i);
|
||||
|
||||
if(reg.getLandBiomes().contains(biome.getLoadKey()))
|
||||
{
|
||||
biome.setInferredType(InferredType.LAND);
|
||||
break;
|
||||
}
|
||||
|
||||
if(reg.getSeaBiomes().contains(biome.getLoadKey()))
|
||||
{
|
||||
biome.setInferredType(InferredType.SEA);
|
||||
break;
|
||||
}
|
||||
|
||||
if(reg.getShoreBiomes().contains(biome.getLoadKey()))
|
||||
{
|
||||
biome.setInferredType(InferredType.SHORE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return biome;
|
||||
}
|
||||
|
||||
double wx = getModifiedX(x, z);
|
||||
double wz = getModifiedZ(x, z);
|
||||
IrisRegion region = glBiome.getRegion(wx, wz);
|
||||
IrisBiome res = glBiome.generateRegionData(wx, wz, x, z, region);
|
||||
|
||||
return res;
|
||||
});
|
||||
return getCache().getRawBiome(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,245 +1,81 @@
|
||||
package com.volmit.iris.gen.atomics;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import com.volmit.iris.IrisSettings;
|
||||
import com.volmit.iris.gen.IrisTerrainProvider;
|
||||
import com.volmit.iris.object.IrisBiome;
|
||||
import com.volmit.iris.object.IrisRegion;
|
||||
import com.volmit.iris.util.KMap;
|
||||
import com.volmit.iris.util.ChunkPosition;
|
||||
|
||||
public class AtomicMulticache
|
||||
{
|
||||
public static boolean broken = false;
|
||||
private final AtomicInteger x;
|
||||
private final AtomicInteger z;
|
||||
private int hit = 0;
|
||||
private int miss = 0;
|
||||
private final KMap<Long, Double> height;
|
||||
private final KMap<Long, Integer> carvedHeight;
|
||||
private final KMap<Long, Integer> carvedHeightIgnoreWater;
|
||||
private final KMap<Long, IrisBiome> biome;
|
||||
private final KMap<Long, IrisBiome> rawBiome;
|
||||
private final KMap<Long, IrisRegion> region;
|
||||
private final LoadingCache<ChunkPosition, Double> height;
|
||||
private final LoadingCache<ChunkPosition, Integer> carvedHeight;
|
||||
private final LoadingCache<ChunkPosition, Integer> carvedHeightIgnoreWater;
|
||||
private final LoadingCache<ChunkPosition, IrisBiome> biome;
|
||||
private final LoadingCache<ChunkPosition, IrisBiome> rawBiome;
|
||||
private final LoadingCache<ChunkPosition, IrisRegion> region;
|
||||
|
||||
public AtomicMulticache()
|
||||
public AtomicMulticache(IrisTerrainProvider gen)
|
||||
{
|
||||
x = new AtomicInteger(0);
|
||||
z = new AtomicInteger(0);
|
||||
height = new KMap<Long, Double>();
|
||||
carvedHeight = new KMap<Long, Integer>();
|
||||
carvedHeightIgnoreWater = new KMap<Long, Integer>();
|
||||
biome = new KMap<Long, IrisBiome>();
|
||||
rawBiome = new KMap<Long, IrisBiome>();
|
||||
region = new KMap<Long, IrisRegion>();
|
||||
}
|
||||
|
||||
public void targetChunk(int x, int z)
|
||||
{
|
||||
if(broken)
|
||||
height = Caffeine.newBuilder().maximumSize(getLimit()).build((c) -> gen.getNoiseHeight(c.getX(), c.getZ()) + gen.getFluidHeight());
|
||||
carvedHeight = Caffeine.newBuilder().maximumSize(getLimit()).build((c) ->
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.x.set(x);
|
||||
this.z.set(z);
|
||||
|
||||
if(!IrisSettings.get().sharedCaching || Iris.lowMemoryMode)
|
||||
int h = (int) Math.round(gen.getTerrainWaterHeight(c.getX(), c.getZ()));
|
||||
h = gen.getGlCarve().getSurfaceCarve(c.getX(), h, c.getZ());
|
||||
return h;
|
||||
});
|
||||
carvedHeightIgnoreWater = Caffeine.newBuilder().maximumSize(getLimit()).build((c) ->
|
||||
{
|
||||
drop();
|
||||
}
|
||||
|
||||
else
|
||||
int h = (int) Math.round(gen.getTerrainHeight(c.getX(), c.getZ()));
|
||||
h = gen.getGlCarve().getSurfaceCarve(c.getX(), h, c.getZ());
|
||||
return h;
|
||||
});
|
||||
biome = Caffeine.newBuilder().maximumSize(getLimit()).build((c) -> gen.sampleTrueBiomeBase(c.getX(), c.getZ()));
|
||||
rawBiome = Caffeine.newBuilder().maximumSize(getLimit()).build((c) -> gen.computeRawBiome(c.getX(), c.getZ()));
|
||||
region = Caffeine.newBuilder().maximumSize(getLimit()).build((c) ->
|
||||
{
|
||||
if(height.size() > getLimit())
|
||||
{
|
||||
height.clear();
|
||||
}
|
||||
|
||||
if(carvedHeight.size() > getLimit())
|
||||
{
|
||||
carvedHeight.clear();
|
||||
}
|
||||
|
||||
if(carvedHeightIgnoreWater.size() > getLimit())
|
||||
{
|
||||
carvedHeightIgnoreWater.clear();
|
||||
}
|
||||
|
||||
if(biome.size() > getLimit())
|
||||
{
|
||||
biome.clear();
|
||||
}
|
||||
|
||||
if(rawBiome.size() > getLimit())
|
||||
{
|
||||
rawBiome.clear();
|
||||
}
|
||||
|
||||
if(region.size() > getLimit())
|
||||
{
|
||||
region.clear();
|
||||
}
|
||||
}
|
||||
double wx = gen.getModifiedX(c.getX(), c.getZ());
|
||||
double wz = gen.getModifiedZ(c.getX(), c.getZ());
|
||||
return gen.getGlBiome().getRegion(wx, wz);
|
||||
});
|
||||
}
|
||||
|
||||
private int getLimit()
|
||||
{
|
||||
return 1024;
|
||||
return IrisSettings.get().getAtomicCacheSize();
|
||||
}
|
||||
|
||||
public double getHeight(int x, int z, Supplier<Double> g)
|
||||
public double getHeight(int x, int z)
|
||||
{
|
||||
if(broken)
|
||||
{
|
||||
return -5784;
|
||||
}
|
||||
|
||||
long pos = pos(x, z);
|
||||
Double r = height.get(pos);
|
||||
|
||||
if(r == null)
|
||||
{
|
||||
miss++;
|
||||
r = g.get();
|
||||
height.put(pos, r);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
hit++;
|
||||
}
|
||||
|
||||
return r;
|
||||
return height.get(new ChunkPosition(x, z));
|
||||
}
|
||||
|
||||
public int getCarvedHeight(int x, int z, Supplier<Integer> g)
|
||||
public int getCarvedHeight(int x, int z)
|
||||
{
|
||||
if(broken)
|
||||
{
|
||||
return -57841;
|
||||
}
|
||||
|
||||
long pos = pos(x, z);
|
||||
Integer r = carvedHeight.get(pos);
|
||||
|
||||
if(r == null)
|
||||
{
|
||||
miss++;
|
||||
r = g.get();
|
||||
carvedHeight.put(pos, r);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
hit++;
|
||||
}
|
||||
|
||||
return r;
|
||||
return carvedHeight.get(new ChunkPosition(x, z));
|
||||
}
|
||||
|
||||
public int getCarvedHeightIgnoreWater(int x, int z, Supplier<Integer> g)
|
||||
public int getCarvedHeightIgnoreWater(int x, int z)
|
||||
{
|
||||
if(broken)
|
||||
{
|
||||
return -57841;
|
||||
}
|
||||
|
||||
long pos = pos(x, z);
|
||||
Integer r = carvedHeightIgnoreWater.get(pos);
|
||||
|
||||
if(r == null)
|
||||
{
|
||||
miss++;
|
||||
r = g.get();
|
||||
carvedHeightIgnoreWater.put(pos, r);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
hit++;
|
||||
}
|
||||
|
||||
return r;
|
||||
return carvedHeightIgnoreWater.get(new ChunkPosition(x, z));
|
||||
}
|
||||
|
||||
public IrisRegion getRegion(int x, int z, Supplier<IrisRegion> g)
|
||||
public IrisRegion getRegion(int x, int z)
|
||||
{
|
||||
long pos = pos(x, z);
|
||||
IrisRegion r = region.get(pos);
|
||||
|
||||
if(r == null)
|
||||
{
|
||||
miss++;
|
||||
r = g.get();
|
||||
region.put(pos, r);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
hit++;
|
||||
}
|
||||
|
||||
return r;
|
||||
return region.get(new ChunkPosition(x, z));
|
||||
}
|
||||
|
||||
public IrisBiome getBiome(int x, int z, Supplier<IrisBiome> g)
|
||||
public IrisBiome getBiome(int x, int z)
|
||||
{
|
||||
long pos = pos(x, z);
|
||||
IrisBiome r = biome.get(pos);
|
||||
|
||||
if(r == null)
|
||||
{
|
||||
miss++;
|
||||
r = g.get();
|
||||
biome.put(pos, r);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
hit++;
|
||||
}
|
||||
|
||||
return r;
|
||||
return biome.get(new ChunkPosition(x, z));
|
||||
}
|
||||
|
||||
public IrisBiome getRawBiome(int x, int z, Supplier<IrisBiome> g)
|
||||
public IrisBiome getRawBiome(int x, int z)
|
||||
{
|
||||
if(broken)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
long pos = pos(x, z);
|
||||
IrisBiome r = rawBiome.get(pos);
|
||||
|
||||
if(r == null)
|
||||
{
|
||||
miss++;
|
||||
r = g.get();
|
||||
rawBiome.put(pos, r);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
hit++;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public double getCacheHitRate()
|
||||
{
|
||||
return (double) hit / (double) (hit + miss);
|
||||
}
|
||||
|
||||
private long pos(int x, int z)
|
||||
{
|
||||
if(broken)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return (((long) x) << 32) | (z & 0xffffffffL);
|
||||
return rawBiome.get(new ChunkPosition(x, z));
|
||||
}
|
||||
|
||||
public void updateHeight(int x, int z, int h)
|
||||
@@ -248,12 +84,12 @@ public class AtomicMulticache
|
||||
{
|
||||
return;
|
||||
}
|
||||
height.put(pos(x, z), (double) h);
|
||||
height.put(new ChunkPosition(x, z), (double) h);
|
||||
}
|
||||
|
||||
public double getSize()
|
||||
{
|
||||
return height.size() + region.size() + biome.size() + rawBiome.size();
|
||||
return height.estimatedSize() + region.estimatedSize() + biome.estimatedSize() + rawBiome.estimatedSize() + carvedHeight.estimatedSize() + carvedHeightIgnoreWater.estimatedSize();
|
||||
}
|
||||
|
||||
public void drop()
|
||||
@@ -263,13 +99,11 @@ public class AtomicMulticache
|
||||
return;
|
||||
}
|
||||
|
||||
hit = 0;
|
||||
miss = 0;
|
||||
height.clear();
|
||||
region.clear();
|
||||
biome.clear();
|
||||
rawBiome.clear();
|
||||
carvedHeight.clear();
|
||||
carvedHeightIgnoreWater.clear();
|
||||
height.invalidateAll();
|
||||
region.invalidateAll();
|
||||
biome.invalidateAll();
|
||||
rawBiome.invalidateAll();
|
||||
carvedHeight.invalidateAll();
|
||||
carvedHeightIgnoreWater.invalidateAll();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user