implement SamplerCache for drastically increased structure perf

This commit is contained in:
dfsek
2021-01-03 13:24:17 -07:00
parent fed24920f8
commit 315230af27
10 changed files with 44 additions and 27 deletions

View File

@@ -21,7 +21,7 @@ import com.dfsek.terra.api.structures.script.builders.UnaryNumberFunctionBuilder
import com.dfsek.terra.api.structures.structure.Rotation;
import com.dfsek.terra.api.structures.structure.buffer.Buffer;
import com.dfsek.terra.api.structures.structure.buffer.StructureBuffer;
import com.dfsek.terra.api.structures.world.CheckCache;
import com.dfsek.terra.generation.math.SamplerCache;
import com.dfsek.terra.registry.LootRegistry;
import com.dfsek.terra.registry.ScriptRegistry;
import net.jafama.FastMath;
@@ -38,7 +38,7 @@ public class StructureScript {
private final String id;
private final LinkedHashMap<Location, StructureBuffer> cache;
public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry, LootRegistry lootRegistry, CheckCache cache) throws ParseException {
public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry, LootRegistry lootRegistry, SamplerCache cache) throws ParseException {
Parser parser;
try {
parser = new Parser(IOUtils.toString(inputStream));

View File

@@ -6,15 +6,15 @@ import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
import com.dfsek.terra.api.structures.script.functions.CheckFunction;
import com.dfsek.terra.api.structures.tokenizer.Position;
import com.dfsek.terra.api.structures.world.CheckCache;
import com.dfsek.terra.generation.math.SamplerCache;
import java.util.List;
public class CheckFunctionBuilder implements FunctionBuilder<CheckFunction> {
private final TerraPlugin main;
private final CheckCache cache;
private final SamplerCache cache;
public CheckFunctionBuilder(TerraPlugin main, CheckCache cache) {
public CheckFunctionBuilder(TerraPlugin main, SamplerCache cache) {
this.main = main;
this.cache = cache;
}

View File

@@ -12,20 +12,20 @@ import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.structure.RotationUtil;
import com.dfsek.terra.api.structures.tokenizer.Position;
import com.dfsek.terra.api.structures.world.CheckCache;
import com.dfsek.terra.api.world.generation.GenerationPhase;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.grid.master.TerraBiomeGrid;
import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.generation.math.SamplerCache;
import net.jafama.FastMath;
public class CheckFunction implements Function<String> {
private final TerraPlugin main;
private final Returnable<Number> x, y, z;
private final Position position;
private final CheckCache cache;
private final SamplerCache cache;
public CheckFunction(TerraPlugin main, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, CheckCache cache, Position position) {
public CheckFunction(TerraPlugin main, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, SamplerCache cache, Position position) {
this.main = main;
this.x = x;
this.y = y;

View File

@@ -9,7 +9,6 @@ import com.dfsek.terra.api.LoaderRegistrar;
import com.dfsek.terra.api.platform.TerraPlugin;
import com.dfsek.terra.api.structures.loot.LootTable;
import com.dfsek.terra.api.structures.script.StructureScript;
import com.dfsek.terra.api.structures.world.CheckCache;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.flora.Flora;
import com.dfsek.terra.api.world.palette.Palette;
@@ -43,6 +42,7 @@ import com.dfsek.terra.config.templates.StructureTemplate;
import com.dfsek.terra.config.templates.TreeTemplate;
import com.dfsek.terra.generation.items.TerraStructure;
import com.dfsek.terra.generation.items.ores.Ore;
import com.dfsek.terra.generation.math.SamplerCache;
import com.dfsek.terra.registry.BiomeGridRegistry;
import com.dfsek.terra.registry.BiomeRegistry;
import com.dfsek.terra.registry.CarverRegistry;
@@ -95,12 +95,12 @@ public class ConfigPack implements LoaderRegistrar {
private final ConfigLoader selfLoader = new ConfigLoader();
private final Scope varScope = new Scope();
private final CheckCache checkCache;
private final SamplerCache samplerCache;
public ConfigPack(File folder, TerraPlugin main) throws ConfigException {
long l = System.nanoTime();
this.checkCache = new CheckCache(main);
this.samplerCache = new SamplerCache(main);
floraRegistry = new FloraRegistry(main);
paletteRegistry = new PaletteRegistry(main);
treeRegistry = new TreeRegistry(main);
@@ -122,7 +122,7 @@ public class ConfigPack implements LoaderRegistrar {
public ConfigPack(ZipFile file, TerraPlugin main) throws ConfigException {
long l = System.nanoTime();
this.checkCache = new CheckCache(main);
this.samplerCache = new SamplerCache(main);
floraRegistry = new FloraRegistry(main);
paletteRegistry = new PaletteRegistry(main);
treeRegistry = new TreeRegistry(main);
@@ -157,7 +157,7 @@ public class ConfigPack implements LoaderRegistrar {
loader.open("structures/data", ".tesf").thenEntries(entries -> {
for(Map.Entry<String, InputStream> entry : entries) {
try {
StructureScript structureScript = new StructureScript(entry.getValue(), main, scriptRegistry, lootRegistry, checkCache);
StructureScript structureScript = new StructureScript(entry.getValue(), main, scriptRegistry, lootRegistry, samplerCache);
scriptRegistry.add(structureScript.getId(), structureScript);
} catch(com.dfsek.terra.api.structures.parser.exceptions.ParseException e) {
throw new LoadException("Unable to load script \"" + entry.getKey() + "\"", e);
@@ -278,7 +278,7 @@ public class ConfigPack implements LoaderRegistrar {
return biomeRegistry;
}
public CheckCache getCheckCache() {
return checkCache;
public SamplerCache getSamplerCache() {
return samplerCache;
}
}

View File

@@ -23,6 +23,7 @@ import com.dfsek.terra.biome.palette.SinglePalette;
import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.generation.math.Sampler;
import com.dfsek.terra.generation.math.SamplerCache;
import com.dfsek.terra.util.PaletteUtil;
import org.jetbrains.annotations.NotNull;
@@ -37,12 +38,15 @@ public class MasterChunkGenerator implements TerraChunkGenerator {
private final MaterialData water;
private final SinglePalette<BlockData> blank;
private final SamplerCache cache;
public MasterChunkGenerator(ConfigPack c, TerraPlugin main) {
public MasterChunkGenerator(ConfigPack c, TerraPlugin main, SamplerCache cache) {
this.configPack = c;
this.main = main;
water = main.getWorldHandle().createMaterialData("minecraft:water");
blank = new SinglePalette<>(main.getWorldHandle().createBlockData("minecraft:air"));
this.cache = cache;
}
@Override
@@ -91,7 +95,7 @@ public class MasterChunkGenerator implements TerraChunkGenerator {
int xOrig = (chunkX << 4);
int zOrig = (chunkZ << 4);
Sampler sampler = new Sampler(chunkX, chunkZ, tw.getGrid(), world, configPack.getTemplate().getElevationBlend(), configPack.getTemplate().getBaseBlend());
Sampler sampler = cache.getChunk(world, chunkX, chunkZ);
for(byte x = 0; x < 16; x++) {
for(byte z = 0; z < 16; z++) {

View File

@@ -1,20 +1,19 @@
package com.dfsek.terra.api.structures.world;
package com.dfsek.terra.generation.math;
import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.api.platform.TerraPlugin;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.generation.math.Sampler;
import net.jafama.FastMath;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
public class CheckCache {
public class SamplerCache {
private final Map<Long, Container> cache;
private final TerraPlugin main;
public CheckCache(TerraPlugin main) {
public SamplerCache(TerraPlugin main) {
cache = new HashMap<>();
this.main = main;
}
@@ -28,6 +27,15 @@ public class CheckCache {
})).get(x, z);
}
public Sampler getChunk(World world, int chunkX, int chunkZ) {
return cache.computeIfAbsent(world.getSeed(), seed -> new Container(world, new LinkedHashMap<Long, Sampler>() {
@Override
protected boolean removeEldestEntry(Map.Entry<Long, Sampler> eldest) {
return size() > main.getTerraConfig().getCheckCache();
}
})).getChunk(chunkX, chunkZ);
}
private class Container {
private final World world;
@@ -41,9 +49,13 @@ public class CheckCache {
public Sampler get(int x, int z) {
int cx = FastMath.floorDiv(x, 16);
int cz = FastMath.floorDiv(z, 16);
return getChunk(cx, cz);
}
public Sampler getChunk(int cx, int cz) {
long key = (((long) cx) << 32) | (cz & 0xffffffffL);
TerraWorld tw = main.getWorld(world);
return cache.computeIfAbsent(key, k -> new Sampler(cx, cz, tw.getGrid(), world, 4, 8));
return cache.computeIfAbsent(key, k -> new Sampler(cx, cz, tw.getGrid(), world, tw.getConfig().getTemplate().getBaseBlend(), tw.getConfig().getTemplate().getElevationBlend()));
}
}
}