mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-03 00:15:35 +00:00
replace dumb caches with guava caches
This commit is contained in:
parent
8fd3530653
commit
cbc2885c16
@ -32,21 +32,21 @@ import com.dfsek.terra.debug.Debug;
|
||||
import com.dfsek.terra.generation.math.SamplerCache;
|
||||
import com.dfsek.terra.registry.LootRegistry;
|
||||
import com.dfsek.terra.registry.ScriptRegistry;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import net.jafama.FastMath;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class StructureScript {
|
||||
private final Block block;
|
||||
private final String id;
|
||||
String tempID;
|
||||
private final Map<Location, StructureBuffer> cache;
|
||||
private final Cache<Location, StructureBuffer> cache;
|
||||
private final TerraPlugin main;
|
||||
|
||||
public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry, LootRegistry lootRegistry, SamplerCache cache) throws ParseException {
|
||||
@ -88,12 +88,7 @@ public class StructureScript {
|
||||
this.id = parser.getID();
|
||||
tempID = id;
|
||||
this.main = main;
|
||||
this.cache = Collections.synchronizedMap(new LinkedHashMap<Location, StructureBuffer>() {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<Location, StructureBuffer> eldest) {
|
||||
return this.size() > main.getTerraConfig().getStructureCache();
|
||||
}
|
||||
});
|
||||
this.cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getStructureCache()).build();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,12 +117,14 @@ public class StructureScript {
|
||||
}
|
||||
|
||||
private StructureBuffer computeBuffer(Location location, Random random, Rotation rotation) {
|
||||
synchronized(cache) {
|
||||
return cache.computeIfAbsent(location, loc -> {
|
||||
StructureBuffer buf = new StructureBuffer(loc);
|
||||
try {
|
||||
return cache.get(location, () -> {
|
||||
StructureBuffer buf = new StructureBuffer(location);
|
||||
buf.setSucceeded(applyBlock(new TerraImplementationArguments(buf, rotation, random, 0)));
|
||||
return buf;
|
||||
});
|
||||
} catch(ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
package com.dfsek.terra.biome;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Vector2;
|
||||
import com.dfsek.terra.biome.pipeline.BiomeHolder;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BiomeCache {
|
||||
LoadingCache<Vector2, BiomeHolder> cache;
|
||||
|
||||
public BiomeCache() {
|
||||
cache = CacheBuilder.newBuilder()
|
||||
.maximumSize(1024)
|
||||
.build(
|
||||
new CacheLoader<Vector2, BiomeHolder>() {
|
||||
@Override
|
||||
public BiomeHolder load(@NotNull Vector2 key) throws Exception {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -50,11 +50,7 @@ public class StandardBiomeProvider implements BiomeProvider {
|
||||
|
||||
@Override
|
||||
public TerraBiome getBiome(int x, int z) {
|
||||
try {
|
||||
return biomeCache.get(new Vector2(x, z));
|
||||
} catch(ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return biomeCache.getUnchecked(new Vector2(x, z));
|
||||
}
|
||||
|
||||
public int getResolution() {
|
||||
|
@ -10,52 +10,50 @@ import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.api.world.carving.Worm;
|
||||
import com.dfsek.terra.biome.BiomeProvider;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class CarverCache {
|
||||
|
||||
private final World w;
|
||||
private final Map<Long, List<Worm.WormPoint>> carvers;
|
||||
private final TerraPlugin main;
|
||||
private final LoadingCache<Long, List<Worm.WormPoint>> cache;
|
||||
private final UserDefinedCarver carver;
|
||||
|
||||
public CarverCache(World w, TerraPlugin main) {
|
||||
this.w = w;
|
||||
this.main = main;
|
||||
carvers = Collections.synchronizedMap(new LinkedHashMap<Long, List<Worm.WormPoint>>() {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry eldest) {
|
||||
return this.size() > main.getTerraConfig().getCarverCacheSize();
|
||||
}
|
||||
});
|
||||
public CarverCache(World w, TerraPlugin main, UserDefinedCarver carver) {
|
||||
this.carver = carver;
|
||||
cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getCarverCacheSize())
|
||||
.build(new CacheLoader<Long, List<Worm.WormPoint>>() {
|
||||
@Override
|
||||
public List<Worm.WormPoint> load(@NotNull Long key) {
|
||||
int chunkX = (int) (key >> 32);
|
||||
int chunkZ = (int) key.longValue();
|
||||
BiomeProvider provider = main.getWorld(w).getBiomeProvider();
|
||||
if(CarverCache.this.carver.isChunkCarved(w, chunkX, chunkZ, new FastRandom(MathUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed() + CarverCache.this.carver.hashCode())))) {
|
||||
long seed = MathUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed());
|
||||
CarverCache.this.carver.getSeedVar().setValue(seed);
|
||||
Random r = new FastRandom(seed);
|
||||
Worm carving = CarverCache.this.carver.getWorm(seed, new Vector3((chunkX << 4) + r.nextInt(16), CarverCache.this.carver.getConfig().getHeight().get(r), (chunkZ << 4) + r.nextInt(16)));
|
||||
List<Worm.WormPoint> points = new GlueList<>();
|
||||
for(int i = 0; i < carving.getLength(); i++) {
|
||||
carving.step();
|
||||
TerraBiome biome = provider.getBiome(carving.getRunning().toLocation(w));
|
||||
if(!((UserDefinedBiome) biome).getConfig().getCarvers().containsKey(CarverCache.this.carver)) { // Stop if we enter a biome this carver is not present in
|
||||
return new GlueList<>();
|
||||
}
|
||||
points.add(carving.getPoint());
|
||||
}
|
||||
return points;
|
||||
}
|
||||
return new GlueList<>();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<Worm.WormPoint> getPoints(int chunkX, int chunkZ, UserDefinedCarver carver) {
|
||||
synchronized(carvers) {
|
||||
return carvers.computeIfAbsent(MathUtil.squash(chunkX, chunkZ), key -> {
|
||||
BiomeProvider provider = main.getWorld(w).getBiomeProvider();
|
||||
if(carver.isChunkCarved(w, chunkX, chunkZ, new FastRandom(MathUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed() + carver.hashCode())))) {
|
||||
long seed = MathUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed());
|
||||
carver.getSeedVar().setValue(seed);
|
||||
Random r = new FastRandom(seed);
|
||||
Worm carving = carver.getWorm(seed, new Vector3((chunkX << 4) + r.nextInt(16), carver.getConfig().getHeight().get(r), (chunkZ << 4) + r.nextInt(16)));
|
||||
List<Worm.WormPoint> points = new GlueList<>();
|
||||
for(int i = 0; i < carving.getLength(); i++) {
|
||||
carving.step();
|
||||
TerraBiome biome = provider.getBiome(carving.getRunning().toLocation(w));
|
||||
if(!((UserDefinedBiome) biome).getConfig().getCarvers().containsKey(carver)) { // Stop if we enter a biome this carver is not present in
|
||||
return new GlueList<>();
|
||||
}
|
||||
points.add(carving.getPoint());
|
||||
}
|
||||
return points;
|
||||
}
|
||||
return new GlueList<>();
|
||||
});
|
||||
}
|
||||
public List<Worm.WormPoint> getPoints(int chunkX, int chunkZ) {
|
||||
return cache.getUnchecked(MathUtil.squash(chunkX, chunkZ));
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import com.dfsek.terra.api.world.carving.Worm;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import com.dfsek.terra.config.templates.CarverTemplate;
|
||||
import com.dfsek.terra.debug.Debug;
|
||||
import net.jafama.FastMath;
|
||||
import parsii.eval.Expression;
|
||||
import parsii.eval.Parser;
|
||||
@ -100,11 +101,12 @@ public class UserDefinedCarver extends Carver {
|
||||
|
||||
@Override
|
||||
public void carve(int chunkX, int chunkZ, World w, BiConsumer<Vector3, CarvingType> consumer) {
|
||||
CarverCache cache = cacheMap.computeIfAbsent(w, world -> new CarverCache(world, main));
|
||||
CarverCache cache = cacheMap.computeIfAbsent(w, world -> new CarverCache(world, main, this));
|
||||
if(cacheMap.size() > 1) Debug.info("Map size: " + cacheMap.size());
|
||||
int carvingRadius = getCarvingRadius();
|
||||
for(int x = chunkX - carvingRadius; x <= chunkX + carvingRadius; x++) {
|
||||
for(int z = chunkZ - carvingRadius; z <= chunkZ + carvingRadius; z++) {
|
||||
cache.getPoints(x, z, this).forEach(point -> {
|
||||
cache.getPoints(x, z).forEach(point -> {
|
||||
Vector3 origin = point.getOrigin();
|
||||
if(FastMath.floorDiv(origin.getBlockX(), 16) != chunkX && FastMath.floorDiv(origin.getBlockZ(), 16) != chunkZ) // We only want to carve this chunk.
|
||||
return;
|
||||
|
@ -4,11 +4,13 @@ import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.api.math.MathUtil;
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import net.jafama.FastMath;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SamplerCache {
|
||||
@ -35,14 +37,18 @@ public class SamplerCache {
|
||||
private class Container {
|
||||
private final World world;
|
||||
private final TerraWorld terraWorld;
|
||||
private final Map<Long, Sampler> cache = Collections.synchronizedMap(new LinkedHashMap<Long, Sampler>() {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<Long, Sampler> eldest) {
|
||||
return this.size() > main.getTerraConfig().getSamplerCache();
|
||||
}
|
||||
});
|
||||
private final LoadingCache<Long, Sampler> cache;
|
||||
|
||||
private Container(World world) {
|
||||
cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getSamplerCache())
|
||||
.build(new CacheLoader<Long, Sampler>() {
|
||||
@Override
|
||||
public Sampler load(@NotNull Long key) {
|
||||
int cx = (int) (key >> 32);
|
||||
int cz = (int) key.longValue();
|
||||
return new Sampler(cx, cz, terraWorld.getBiomeProvider(), world, terraWorld.getConfig().getTemplate().getBaseBlend(), terraWorld.getConfig().getTemplate().getElevationBlend());
|
||||
}
|
||||
});
|
||||
this.world = world;
|
||||
terraWorld = main.getWorld(world);
|
||||
}
|
||||
@ -55,9 +61,7 @@ public class SamplerCache {
|
||||
|
||||
public Sampler getChunk(int cx, int cz) {
|
||||
long key = MathUtil.squash(cx, cz);
|
||||
synchronized(cache) {
|
||||
return cache.computeIfAbsent(key, k -> new Sampler(cx, cz, terraWorld.getBiomeProvider(), world, terraWorld.getConfig().getTemplate().getBaseBlend(), terraWorld.getConfig().getTemplate().getElevationBlend()));
|
||||
}
|
||||
return cache.getUnchecked(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,25 +61,21 @@ public class BiomeTest {
|
||||
BiomeSource source = new RandomSource(climate, sourceSampler);
|
||||
|
||||
|
||||
BiomeProvider provider = new StandardBiomeProvider.StandardBiomeProviderBuilder((seed) -> {
|
||||
BiomePipeline pipeline = new BiomePipeline.BiomePipelineBuilder(2)
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(1))))
|
||||
.addStage(new MutatorStage(new ReplaceMutator("OCEAN_TEMP", oceanBiomes, whiteNoise(243))))
|
||||
.addStage(new MutatorStage(new ReplaceMutator("LAND_TEMP", landBiomes, whiteNoise(243))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(2))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(2))))
|
||||
.addStage(new MutatorStage(new SmoothMutator(whiteNoise(3))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(4))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(4))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(4))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(4))))
|
||||
.addStage(new MutatorStage(new BorderMutator("OCEAN", "LAND", whiteNoise(1234), beachBiomes)))
|
||||
.addStage(new MutatorStage(new SmoothMutator(whiteNoise(6))))
|
||||
.addStage(new MutatorStage(new SmoothMutator(whiteNoise(6))))
|
||||
.build(source);
|
||||
System.out.println("Size: " + pipeline.getSize());
|
||||
return pipeline;
|
||||
}, null).build(0);
|
||||
BiomeProvider provider = new StandardBiomeProvider.StandardBiomeProviderBuilder((seed) -> new BiomePipeline.BiomePipelineBuilder(2)
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(1))))
|
||||
.addStage(new MutatorStage(new ReplaceMutator("OCEAN_TEMP", oceanBiomes, whiteNoise(243))))
|
||||
.addStage(new MutatorStage(new ReplaceMutator("LAND_TEMP", landBiomes, whiteNoise(243))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(2))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(2))))
|
||||
.addStage(new MutatorStage(new SmoothMutator(whiteNoise(3))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(4))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(4))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(4))))
|
||||
.addStage(new ExpanderStage(new FractalExpander(whiteNoise(4))))
|
||||
.addStage(new MutatorStage(new BorderMutator("OCEAN", "LAND", whiteNoise(1234), beachBiomes)))
|
||||
.addStage(new MutatorStage(new SmoothMutator(whiteNoise(6))))
|
||||
.addStage(new MutatorStage(new SmoothMutator(whiteNoise(6))))
|
||||
.build(source), null).build(0);
|
||||
|
||||
|
||||
int size = 1000;
|
||||
|
Loading…
x
Reference in New Issue
Block a user