mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-02 16:05:29 +00:00
More cache improvements
This commit is contained in:
parent
a743e9c015
commit
9d328b12b3
@ -8,7 +8,7 @@ import com.dfsek.terra.addons.noise.samplers.LinearHeightmapSampler;
|
|||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
|
||||||
|
|
||||||
public class CacheSamplerTemplate extends SamplerTemplate<LinearHeightmapSampler> {
|
public class CacheSamplerTemplate extends SamplerTemplate<CacheSampler> {
|
||||||
@Value("sampler")
|
@Value("sampler")
|
||||||
@Default
|
@Default
|
||||||
private NoiseSampler sampler;
|
private NoiseSampler sampler;
|
||||||
|
@ -5,15 +5,16 @@ import com.dfsek.terra.api.noise.NoiseSampler;
|
|||||||
|
|
||||||
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 static com.dfsek.terra.api.util.CacheUtils.CACHE_EXECUTOR;
|
||||||
|
|
||||||
|
|
||||||
public class CacheSampler implements DerivativeNoiseSampler {
|
public class CacheSampler implements NoiseSampler {
|
||||||
|
|
||||||
private final NoiseSampler sampler;
|
private final NoiseSampler sampler;
|
||||||
private final LoadingCache<DoubleSeededVector2, Double> cache2D;
|
private final LoadingCache<DoubleSeededVector2, Double> cache2D;
|
||||||
private final LoadingCache<DoubleSeededVector3, Double> cache3D;
|
private final LoadingCache<DoubleSeededVector3, Double> cache3D;
|
||||||
private final LoadingCache<DoubleSeededVector2, double[]> cache2DDirv;
|
|
||||||
private final LoadingCache<DoubleSeededVector3, double[]> cache3DDirv;
|
|
||||||
|
|
||||||
private final ThreadLocal<DoubleSeededVector2> mutable2 =
|
private final ThreadLocal<DoubleSeededVector2> mutable2 =
|
||||||
ThreadLocal.withInitial(() -> new DoubleSeededVector2(0, 0, 0));
|
ThreadLocal.withInitial(() -> new DoubleSeededVector2(0, 0, 0));
|
||||||
@ -23,83 +24,41 @@ public class CacheSampler implements DerivativeNoiseSampler {
|
|||||||
|
|
||||||
public CacheSampler(NoiseSampler sampler, int dimensions, int generationThreads) {
|
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
|
this.cache2D = Caffeine
|
||||||
.newBuilder()
|
.newBuilder()
|
||||||
.initialCapacity(0)
|
.executor(CACHE_EXECUTOR)
|
||||||
.maximumSize(256L * generationThreads)// 1 full chunk (high res)
|
.scheduler(Scheduler.systemScheduler())
|
||||||
|
.initialCapacity(size)
|
||||||
|
.maximumSize(size)
|
||||||
.build(vec -> {
|
.build(vec -> {
|
||||||
mutable2.remove();
|
mutable2.remove();
|
||||||
return sampler.noise(vec.seed, vec.x, vec.z);
|
return this.sampler.noise(vec.seed, vec.x, vec.z);
|
||||||
});
|
});
|
||||||
cache3D = null;
|
cache3D = null;
|
||||||
cache3DDirv = null;
|
|
||||||
mutable3.remove();
|
mutable3.remove();
|
||||||
if (DerivativeNoiseSampler.isDifferentiable(sampler)) {
|
|
||||||
this.cache2DDirv = Caffeine
|
|
||||||
.newBuilder()
|
|
||||||
.initialCapacity(0)
|
|
||||||
.maximumSize(256L * generationThreads) // 1 full chunk (high res)
|
|
||||||
.build(vec -> {
|
|
||||||
mutable2.remove();
|
|
||||||
return ((DerivativeNoiseSampler) sampler).noised(vec.seed, vec.x, vec.z);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
cache2DDirv = null;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
int size3D = size * 384;
|
||||||
this.cache3D = Caffeine
|
this.cache3D = Caffeine
|
||||||
.newBuilder()
|
.newBuilder()
|
||||||
.initialCapacity(0)
|
.executor(CACHE_EXECUTOR)
|
||||||
.maximumSize(256L * generationThreads) // 1 full chunk (high res)
|
.scheduler(Scheduler.systemScheduler())
|
||||||
|
.initialCapacity(size3D)
|
||||||
|
.maximumSize(size3D)
|
||||||
.build(vec -> {
|
.build(vec -> {
|
||||||
mutable3.remove();
|
mutable3.remove();
|
||||||
return sampler.noise(vec.seed, vec.x, vec.y, vec.z);
|
return this.sampler.noise(vec.seed, vec.x, vec.y, vec.z);
|
||||||
});
|
});
|
||||||
cache2D = null;
|
cache2D = null;
|
||||||
cache2DDirv = null;
|
|
||||||
mutable2.remove();
|
mutable2.remove();
|
||||||
if (DerivativeNoiseSampler.isDifferentiable(sampler)) {
|
|
||||||
this.cache3DDirv = Caffeine
|
|
||||||
.newBuilder()
|
|
||||||
.initialCapacity(0)
|
|
||||||
.maximumSize(256L * generationThreads) // 1 full chunk (high res)
|
|
||||||
.build(vec -> {
|
|
||||||
mutable3.remove();
|
|
||||||
return ((DerivativeNoiseSampler) sampler).noised(vec.seed, vec.x, vec.y, vec.z);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
cache3DDirv = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDifferentiable() {
|
|
||||||
return DerivativeNoiseSampler.isDifferentiable(sampler);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double[] noised(long seed, double x, double y) {
|
|
||||||
DoubleSeededVector2 mutableKey = mutable2.get();
|
|
||||||
mutableKey.set(x, y, seed);
|
|
||||||
return cache2DDirv.get(mutableKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double[] noised(long seed, double x, double y, double z) {
|
|
||||||
DoubleSeededVector3 mutableKey = mutable3.get();
|
|
||||||
mutableKey.set(x, y, z, seed);
|
|
||||||
return cache3DDirv.get(mutableKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double noise(long seed, double x, double y) {
|
public double noise(long seed, double x, double y) {
|
||||||
DoubleSeededVector2 mutableKey = mutable2.get();
|
DoubleSeededVector2 mutableKey = mutable2.get();
|
||||||
mutableKey.set(x, y, seed);
|
mutableKey.set(x, y, seed);
|
||||||
if (cache2DDirv != null && cache2DDirv.estimatedSize() != 0) {
|
|
||||||
return cache2DDirv.get(mutableKey)[0];
|
|
||||||
}
|
|
||||||
return cache2D.get(mutableKey);
|
return cache2D.get(mutableKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,9 +66,6 @@ public class CacheSampler implements DerivativeNoiseSampler {
|
|||||||
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();
|
DoubleSeededVector3 mutableKey = mutable3.get();
|
||||||
mutableKey.set(x, y, z, seed);
|
mutableKey.set(x, y, z, seed);
|
||||||
if (cache3DDirv != null && cache3DDirv.estimatedSize() != 0) {
|
|
||||||
return cache3DDirv.get(mutableKey)[0];
|
|
||||||
}
|
|
||||||
return cache3D.get(mutableKey);
|
return cache3D.get(mutableKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.dfsek.terra.api.util;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
|
||||||
|
public class CacheUtils {
|
||||||
|
public static final Executor CACHE_EXECUTOR = Executors.newSingleThreadExecutor();
|
||||||
|
}
|
@ -9,6 +9,8 @@ import java.util.Optional;
|
|||||||
import com.dfsek.terra.api.Handle;
|
import com.dfsek.terra.api.Handle;
|
||||||
import com.dfsek.terra.api.world.biome.Biome;
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
import static com.dfsek.terra.api.util.CacheUtils.CACHE_EXECUTOR;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A biome provider implementation that lazily evaluates biomes, and caches them.
|
* A biome provider implementation that lazily evaluates biomes, and caches them.
|
||||||
@ -30,24 +32,32 @@ public class CachingBiomeProvider implements BiomeProvider, Handle {
|
|||||||
protected CachingBiomeProvider(BiomeProvider delegate, int generationThreads) {
|
protected CachingBiomeProvider(BiomeProvider delegate, int generationThreads) {
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
this.res = delegate.resolution();
|
this.res = delegate.resolution();
|
||||||
int size = generationThreads * 256 * 384;
|
|
||||||
|
int size = generationThreads * 256;
|
||||||
|
this.baseCache = Caffeine
|
||||||
|
.newBuilder()
|
||||||
|
.executor(CACHE_EXECUTOR)
|
||||||
|
.scheduler(Scheduler.systemScheduler())
|
||||||
|
.initialCapacity(size)
|
||||||
|
.maximumSize(size)
|
||||||
|
.build(vec -> {
|
||||||
|
mutable2.remove();
|
||||||
|
return delegate.getBaseBiome(vec.x * res, vec.z * res, vec.seed);
|
||||||
|
});
|
||||||
|
|
||||||
|
int size3D = size * 384;
|
||||||
this.cache = Caffeine
|
this.cache = Caffeine
|
||||||
.newBuilder()
|
.newBuilder()
|
||||||
.scheduler(Scheduler.disabledScheduler())
|
.executor(CACHE_EXECUTOR)
|
||||||
.initialCapacity(size)
|
.scheduler(Scheduler.systemScheduler())
|
||||||
.maximumSize(size) // 1 full chunk (high res)
|
.initialCapacity(size3D)
|
||||||
|
.maximumSize(size3D)
|
||||||
.build(vec -> {
|
.build(vec -> {
|
||||||
mutable3.remove();
|
mutable3.remove();
|
||||||
return delegate.getBiome(vec.x * res, vec.y * res, vec.z * res, vec.seed);
|
return delegate.getBiome(vec.x * res, vec.y * res, vec.z * res, vec.seed);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.baseCache = Caffeine
|
|
||||||
.newBuilder()
|
|
||||||
.maximumSize(256L * generationThreads) // 1 full chunk (high res)
|
|
||||||
.build(vec -> {
|
|
||||||
mutable2.remove();
|
|
||||||
return delegate.getBaseBiome(vec.x * res, vec.z * res, vec.seed);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user