mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-06-18 14:50:56 +00:00
More cache improvements
This commit is contained in:
+1
-1
@@ -151,7 +151,7 @@ public class NoiseAddon implements AddonInitializer {
|
|||||||
noiseRegistry.register(addon.key("MAX"), () -> new BinaryArithmeticTemplate<>(MaxSampler::new));
|
noiseRegistry.register(addon.key("MAX"), () -> new BinaryArithmeticTemplate<>(MaxSampler::new));
|
||||||
noiseRegistry.register(addon.key("MIN"), () -> new BinaryArithmeticTemplate<>(MinSampler::new));
|
noiseRegistry.register(addon.key("MIN"), () -> new BinaryArithmeticTemplate<>(MinSampler::new));
|
||||||
|
|
||||||
noiseRegistry.register(addon.key("CACHE"), () -> new CacheSamplerTemplate(plugin.getGenerationThreads()));
|
noiseRegistry.register(addon.key("CACHE"), CacheSamplerTemplate::new);
|
||||||
|
|
||||||
|
|
||||||
Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>();
|
Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>();
|
||||||
|
|||||||
+2
-4
@@ -13,14 +13,12 @@ public class CacheSamplerTemplate extends SamplerTemplate<CacheSampler> {
|
|||||||
@Default
|
@Default
|
||||||
private NoiseSampler sampler;
|
private NoiseSampler sampler;
|
||||||
|
|
||||||
private final int generationThreads;
|
public CacheSamplerTemplate() {
|
||||||
|
|
||||||
public CacheSamplerTemplate(int generationThreads) {
|
|
||||||
this.generationThreads = generationThreads;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NoiseSampler get() {
|
public NoiseSampler get() {
|
||||||
return new CacheSampler(sampler, getDimensions(), generationThreads);
|
return new CacheSampler(sampler, getDimensions());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-33
@@ -3,6 +3,10 @@ package com.dfsek.terra.addons.noise.samplers;
|
|||||||
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.generic.pair.Pair;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.generic.pair.Pair.Mutable;
|
||||||
|
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||||
import com.github.benmanes.caffeine.cache.Scheduler;
|
import com.github.benmanes.caffeine.cache.Scheduler;
|
||||||
@@ -13,60 +17,58 @@ import static com.dfsek.terra.api.util.CacheUtils.CACHE_EXECUTOR;
|
|||||||
public class CacheSampler implements NoiseSampler {
|
public class CacheSampler implements NoiseSampler {
|
||||||
|
|
||||||
private final NoiseSampler sampler;
|
private final NoiseSampler sampler;
|
||||||
private final LoadingCache<DoubleSeededVector2, Double> cache2D;
|
private final ThreadLocal<Mutable<DoubleSeededVector2, LoadingCache<DoubleSeededVector2, Double>>> cache2D;
|
||||||
private final LoadingCache<DoubleSeededVector3, Double> cache3D;
|
private final ThreadLocal<Mutable<DoubleSeededVector3, LoadingCache<DoubleSeededVector3, Double>>> cache3D;
|
||||||
|
|
||||||
private final ThreadLocal<DoubleSeededVector2> mutable2 =
|
public CacheSampler(NoiseSampler sampler, int dimensions) {
|
||||||
ThreadLocal.withInitial(() -> new DoubleSeededVector2(0, 0, 0));
|
|
||||||
|
|
||||||
private final ThreadLocal<DoubleSeededVector3> mutable3 =
|
|
||||||
ThreadLocal.withInitial(() -> new DoubleSeededVector3(0, 0, 0, 0));
|
|
||||||
|
|
||||||
public CacheSampler(NoiseSampler sampler, int dimensions, int generationThreads) {
|
|
||||||
this.sampler = sampler;
|
this.sampler = sampler;
|
||||||
int size = generationThreads * 256;
|
|
||||||
if (dimensions == 2) {
|
if (dimensions == 2) {
|
||||||
this.cache2D = Caffeine
|
LoadingCache<DoubleSeededVector2, Double> cache = Caffeine
|
||||||
.newBuilder()
|
.newBuilder()
|
||||||
.executor(CACHE_EXECUTOR)
|
.executor(CACHE_EXECUTOR)
|
||||||
.scheduler(Scheduler.systemScheduler())
|
.scheduler(Scheduler.systemScheduler())
|
||||||
.initialCapacity(size)
|
.initialCapacity(256)
|
||||||
.maximumSize(size)
|
.maximumSize(256)
|
||||||
.build(vec -> {
|
.build(this::sampleNoise);
|
||||||
mutable2.remove();
|
this.cache2D = ThreadLocal.withInitial(() -> Pair.of(new DoubleSeededVector2(0, 0, 0), cache).mutable());
|
||||||
return this.sampler.noise(vec.seed, vec.x, vec.z);
|
this.cache3D = null;
|
||||||
});
|
|
||||||
cache3D = null;
|
|
||||||
mutable3.remove();
|
|
||||||
} else {
|
} else {
|
||||||
int size3D = size * 384;
|
LoadingCache<DoubleSeededVector3, Double> cache = Caffeine
|
||||||
this.cache3D = Caffeine
|
|
||||||
.newBuilder()
|
.newBuilder()
|
||||||
.executor(CACHE_EXECUTOR)
|
.executor(CACHE_EXECUTOR)
|
||||||
.scheduler(Scheduler.systemScheduler())
|
.scheduler(Scheduler.systemScheduler())
|
||||||
.initialCapacity(size3D)
|
.initialCapacity(981504)
|
||||||
.maximumSize(size3D)
|
.maximumSize(981504)
|
||||||
.build(vec -> {
|
.build(this::sampleNoise);
|
||||||
mutable3.remove();
|
this.cache3D = ThreadLocal.withInitial(() -> Pair.of(new DoubleSeededVector3(0, 0, 0, 0), cache).mutable());
|
||||||
return this.sampler.noise(vec.seed, vec.x, vec.y, vec.z);
|
this.cache2D = null;
|
||||||
});
|
|
||||||
cache2D = null;
|
|
||||||
mutable2.remove();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Double sampleNoise(DoubleSeededVector2 vec) {
|
||||||
|
this.cache2D.get().setLeft(new DoubleSeededVector2(0, 0, 0));
|
||||||
|
return this.sampler.noise(vec.seed, vec.x, vec.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Double sampleNoise(DoubleSeededVector3 vec) {
|
||||||
|
this.cache3D.get().setLeft(new DoubleSeededVector3(0, 0, 0, 0));
|
||||||
|
return this.sampler.noise(vec.seed, vec.x, vec.z);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double noise(long seed, double x, double y) {
|
public double noise(long seed, double x, double y) {
|
||||||
DoubleSeededVector2 mutableKey = mutable2.get();
|
Mutable<DoubleSeededVector2, LoadingCache<DoubleSeededVector2, Double>> cachePair = cache2D.get();
|
||||||
|
DoubleSeededVector2 mutableKey = cachePair.getLeft();
|
||||||
mutableKey.set(x, y, seed);
|
mutableKey.set(x, y, seed);
|
||||||
return cache2D.get(mutableKey);
|
return cachePair.getRight().get(mutableKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double noise(long seed, double x, double y, double z) {
|
public double noise(long seed, double x, double y, double z) {
|
||||||
DoubleSeededVector3 mutableKey = mutable3.get();
|
Mutable<DoubleSeededVector3, LoadingCache<DoubleSeededVector3, Double>> cachePair = cache3D.get();
|
||||||
|
DoubleSeededVector3 mutableKey = cachePair.getLeft();
|
||||||
mutableKey.set(x, y, z, seed);
|
mutableKey.set(x, y, z, seed);
|
||||||
return cache3D.get(mutableKey);
|
return cachePair.getRight().get(mutableKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DoubleSeededVector3 {
|
private static class DoubleSeededVector3 {
|
||||||
|
|||||||
+1
-1
@@ -97,7 +97,7 @@ public interface BiomeProvider {
|
|||||||
if(this instanceof CachingBiomeProvider cachingBiomeProvider) {
|
if(this instanceof CachingBiomeProvider cachingBiomeProvider) {
|
||||||
return cachingBiomeProvider;
|
return cachingBiomeProvider;
|
||||||
}
|
}
|
||||||
return new CachingBiomeProvider(this, platform.getGenerationThreads());
|
return new CachingBiomeProvider(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+33
-29
@@ -1,5 +1,9 @@
|
|||||||
package com.dfsek.terra.api.world.biome.generation;
|
package com.dfsek.terra.api.world.biome.generation;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.generic.pair.Pair;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.generic.pair.Pair.Mutable;
|
||||||
|
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||||
import com.github.benmanes.caffeine.cache.Scheduler;
|
import com.github.benmanes.caffeine.cache.Scheduler;
|
||||||
@@ -20,47 +24,45 @@ import static com.dfsek.terra.api.util.CacheUtils.CACHE_EXECUTOR;
|
|||||||
public class CachingBiomeProvider implements BiomeProvider, Handle {
|
public class CachingBiomeProvider implements BiomeProvider, Handle {
|
||||||
protected final BiomeProvider delegate;
|
protected final BiomeProvider delegate;
|
||||||
private final int res;
|
private final int res;
|
||||||
private final LoadingCache<SeededVector3, Biome> cache;
|
private final ThreadLocal<Pair.Mutable<SeededVector3, LoadingCache<SeededVector3, Biome>>> cache;
|
||||||
private final LoadingCache<SeededVector2, Optional<Biome>> baseCache;
|
private final ThreadLocal<Pair.Mutable<SeededVector2, LoadingCache<SeededVector2, Optional<Biome>>>> baseCache;
|
||||||
|
|
||||||
private final ThreadLocal<SeededVector2> mutable2 =
|
protected CachingBiomeProvider(BiomeProvider delegate) {
|
||||||
ThreadLocal.withInitial(() -> new SeededVector2(0, 0, 0));
|
|
||||||
|
|
||||||
private final ThreadLocal<SeededVector3> mutable3 =
|
|
||||||
ThreadLocal.withInitial(() -> new SeededVector3(0, 0, 0, 0));
|
|
||||||
|
|
||||||
protected CachingBiomeProvider(BiomeProvider delegate, int generationThreads) {
|
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
this.res = delegate.resolution();
|
this.res = delegate.resolution();
|
||||||
|
|
||||||
int size = generationThreads * 256;
|
LoadingCache<SeededVector2, Optional<Biome>> cache = Caffeine
|
||||||
this.baseCache = Caffeine
|
|
||||||
.newBuilder()
|
.newBuilder()
|
||||||
.executor(CACHE_EXECUTOR)
|
.executor(CACHE_EXECUTOR)
|
||||||
.scheduler(Scheduler.systemScheduler())
|
.scheduler(Scheduler.systemScheduler())
|
||||||
.initialCapacity(size)
|
.initialCapacity(256)
|
||||||
.maximumSize(size)
|
.maximumSize(256)
|
||||||
.build(vec -> {
|
.build(this::sampleBiome);
|
||||||
mutable2.remove();
|
this.baseCache = ThreadLocal.withInitial(() -> Pair.of(new SeededVector2(0, 0, 0), cache).mutable());
|
||||||
return delegate.getBaseBiome(vec.x * res, vec.z * res, vec.seed);
|
|
||||||
});
|
|
||||||
|
|
||||||
int size3D = size * 384;
|
LoadingCache<SeededVector3, Biome> cache3D = Caffeine
|
||||||
this.cache = Caffeine
|
|
||||||
.newBuilder()
|
.newBuilder()
|
||||||
.executor(CACHE_EXECUTOR)
|
.executor(CACHE_EXECUTOR)
|
||||||
.scheduler(Scheduler.systemScheduler())
|
.scheduler(Scheduler.systemScheduler())
|
||||||
.initialCapacity(size3D)
|
.initialCapacity(981504)
|
||||||
.maximumSize(size3D)
|
.maximumSize(981504)
|
||||||
.build(vec -> {
|
.build(this::sampleBiome);
|
||||||
mutable3.remove();
|
this.cache = ThreadLocal.withInitial(() -> Pair.of(new SeededVector3(0, 0, 0, 0), cache3D).mutable());
|
||||||
return delegate.getBiome(vec.x * res, vec.y * res, vec.z * res, vec.seed);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Optional<Biome> sampleBiome(SeededVector2 vec) {
|
||||||
|
this.baseCache.get().setLeft(new SeededVector2(0, 0, 0));
|
||||||
|
return this.delegate.getBaseBiome(vec.x * res, vec.z * res, vec.seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Biome sampleBiome(SeededVector3 vec) {
|
||||||
|
this.cache.get().setLeft(new SeededVector3(0, 0, 0, 0));
|
||||||
|
return this.delegate.getBiome(vec.x * res, vec.y * res, vec.z * res, vec.seed);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiomeProvider getHandle() {
|
public BiomeProvider getHandle() {
|
||||||
return delegate;
|
return delegate;
|
||||||
@@ -68,16 +70,18 @@ public class CachingBiomeProvider implements BiomeProvider, Handle {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Biome getBiome(int x, int y, int z, long seed) {
|
public Biome getBiome(int x, int y, int z, long seed) {
|
||||||
SeededVector3 mutableKey = mutable3.get();
|
Mutable<SeededVector3, LoadingCache<SeededVector3, Biome>> cachePair = cache.get();
|
||||||
|
SeededVector3 mutableKey = cachePair.getLeft();
|
||||||
mutableKey.set(x, y, z, seed);
|
mutableKey.set(x, y, z, seed);
|
||||||
return cache.get(mutableKey);
|
return cachePair.getRight().get(mutableKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Biome> getBaseBiome(int x, int z, long seed) {
|
public Optional<Biome> getBaseBiome(int x, int z, long seed) {
|
||||||
SeededVector2 mutableKey = mutable2.get();
|
Mutable<SeededVector2, LoadingCache<SeededVector2, Optional<Biome>>> cachePair = baseCache.get();
|
||||||
|
SeededVector2 mutableKey = cachePair.getLeft();
|
||||||
mutableKey.set(x, z, seed);
|
mutableKey.set(x, z, seed);
|
||||||
return baseCache.get(mutableKey);
|
return cachePair.getRight().get(mutableKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user