Improve linear region efficiency by caching the whole region-file data

This commit is contained in:
Lukas Rieger (Blue) 2024-02-23 00:55:11 +01:00
parent dbde93c9f5
commit 3a1e723a51
No known key found for this signature in database
GPG Key ID: AA33883B1BBA03E6
2 changed files with 28 additions and 16 deletions

View File

@ -56,7 +56,7 @@ public class MCAWorld implements World {
private final ChunkLoader chunkLoader = new ChunkLoader(this);
private final LoadingCache<Vector2i, Region> regionCache = Caffeine.newBuilder()
.executor(BlueMap.THREAD_POOL)
.maximumSize(64)
.maximumSize(32)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(this::loadRegion);
private final LoadingCache<Vector2i, Chunk> chunkCache = Caffeine.newBuilder()
@ -176,11 +176,13 @@ public void preloadRegionChunks(int x, int z) {
@Override
public void invalidateChunkCache() {
regionCache.invalidateAll();
chunkCache.invalidateAll();
}
@Override
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));
}

View File

@ -69,6 +69,16 @@ public class LinearRegion implements Region {
private final Path regionFile;
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 {
this.world = world;
this.regionFile = regionFile;
@ -86,26 +96,14 @@ public LinearRegion(MCAWorld world, Vector2i regionPos) throws IllegalArgumentEx
this.regionFile = world.getRegionFolder().resolve(getRegionFileName(regionPos.getX(), regionPos.getY()));
}
@Override
public void iterateAllChunks(ChunkConsumer consumer) throws IOException {
private synchronized void init() throws IOException {
if (initialized) return;
if (Files.notExists(regionFile)) return;
long fileLength = Files.size(regionFile);
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 (
InputStream in = Files.newInputStream(regionFile, StandardOpenOption.READ);
BufferedInputStream bIn = new BufferedInputStream(in);
@ -136,6 +134,18 @@ public void iterateAllChunks(ChunkConsumer consumer) throws IOException {
}
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 (
InputStream in = new ZstdInputStream(new ByteArrayInputStream(compressedData));
BufferedInputStream bIn = new BufferedInputStream(in);