Improve linear region efficiency by caching the whole region-file data
This commit is contained in:
parent
dbde93c9f5
commit
3a1e723a51
|
@ -56,7 +56,7 @@ public class MCAWorld implements World {
|
||||||
private final ChunkLoader chunkLoader = new ChunkLoader(this);
|
private final ChunkLoader chunkLoader = new ChunkLoader(this);
|
||||||
private final LoadingCache<Vector2i, Region> regionCache = Caffeine.newBuilder()
|
private final LoadingCache<Vector2i, Region> regionCache = Caffeine.newBuilder()
|
||||||
.executor(BlueMap.THREAD_POOL)
|
.executor(BlueMap.THREAD_POOL)
|
||||||
.maximumSize(64)
|
.maximumSize(32)
|
||||||
.expireAfterWrite(10, TimeUnit.MINUTES)
|
.expireAfterWrite(10, TimeUnit.MINUTES)
|
||||||
.build(this::loadRegion);
|
.build(this::loadRegion);
|
||||||
private final LoadingCache<Vector2i, Chunk> chunkCache = Caffeine.newBuilder()
|
private final LoadingCache<Vector2i, Chunk> chunkCache = Caffeine.newBuilder()
|
||||||
|
@ -176,11 +176,13 @@ public class MCAWorld implements World {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidateChunkCache() {
|
public void invalidateChunkCache() {
|
||||||
|
regionCache.invalidateAll();
|
||||||
chunkCache.invalidateAll();
|
chunkCache.invalidateAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidateChunkCache(int x, int z) {
|
public void invalidateChunkCache(int x, int z) {
|
||||||
|
regionCache.invalidate(VECTOR_2_I_CACHE.get(x >> 5, z >> 5));
|
||||||
chunkCache.invalidate(VECTOR_2_I_CACHE.get(x, z));
|
chunkCache.invalidate(VECTOR_2_I_CACHE.get(x, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,16 @@ public class LinearRegion implements Region {
|
||||||
private final Path regionFile;
|
private final Path regionFile;
|
||||||
private final Vector2i regionPos;
|
private final Vector2i regionPos;
|
||||||
|
|
||||||
|
private boolean initialized = false;
|
||||||
|
|
||||||
|
private byte version;
|
||||||
|
private long newestTimestamp;
|
||||||
|
private byte compressionLevel;
|
||||||
|
private short chunkCount;
|
||||||
|
private int dataLength;
|
||||||
|
private long dataHash;
|
||||||
|
private byte[] compressedData;
|
||||||
|
|
||||||
public LinearRegion(MCAWorld world, Path regionFile) throws IllegalArgumentException {
|
public LinearRegion(MCAWorld world, Path regionFile) throws IllegalArgumentException {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.regionFile = regionFile;
|
this.regionFile = regionFile;
|
||||||
|
@ -86,26 +96,14 @@ public class LinearRegion implements Region {
|
||||||
this.regionFile = world.getRegionFolder().resolve(getRegionFileName(regionPos.getX(), regionPos.getY()));
|
this.regionFile = world.getRegionFolder().resolve(getRegionFileName(regionPos.getX(), regionPos.getY()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private synchronized void init() throws IOException {
|
||||||
public void iterateAllChunks(ChunkConsumer consumer) throws IOException {
|
if (initialized) return;
|
||||||
|
|
||||||
if (Files.notExists(regionFile)) return;
|
if (Files.notExists(regionFile)) return;
|
||||||
|
|
||||||
long fileLength = Files.size(regionFile);
|
long fileLength = Files.size(regionFile);
|
||||||
if (fileLength == 0) return;
|
if (fileLength == 0) return;
|
||||||
|
|
||||||
int chunkStartX = regionPos.getX() * 32;
|
|
||||||
int chunkStartZ = regionPos.getY() * 32;
|
|
||||||
|
|
||||||
byte[] chunkDataBuffer = null;
|
|
||||||
byte[] compressedData;
|
|
||||||
|
|
||||||
byte version;
|
|
||||||
long newestTimestamp;
|
|
||||||
byte compressionLevel;
|
|
||||||
short chunkCount;
|
|
||||||
int dataLength;
|
|
||||||
long dataHash;
|
|
||||||
|
|
||||||
try (
|
try (
|
||||||
InputStream in = Files.newInputStream(regionFile, StandardOpenOption.READ);
|
InputStream in = Files.newInputStream(regionFile, StandardOpenOption.READ);
|
||||||
BufferedInputStream bIn = new BufferedInputStream(in);
|
BufferedInputStream bIn = new BufferedInputStream(in);
|
||||||
|
@ -136,6 +134,18 @@ public class LinearRegion implements Region {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void iterateAllChunks(ChunkConsumer consumer) throws IOException {
|
||||||
|
if (!initialized) init();
|
||||||
|
|
||||||
|
int chunkStartX = regionPos.getX() * 32;
|
||||||
|
int chunkStartZ = regionPos.getY() * 32;
|
||||||
|
|
||||||
|
byte[] chunkDataBuffer = null;
|
||||||
|
|
||||||
try (
|
try (
|
||||||
InputStream in = new ZstdInputStream(new ByteArrayInputStream(compressedData));
|
InputStream in = new ZstdInputStream(new ByteArrayInputStream(compressedData));
|
||||||
BufferedInputStream bIn = new BufferedInputStream(in);
|
BufferedInputStream bIn = new BufferedInputStream(in);
|
||||||
|
|
Loading…
Reference in New Issue