fix adding chunks to region while being saved

This commit is contained in:
Julian Krings 2025-02-09 12:32:08 +01:00
parent e9d1b9f18e
commit 2087ba88b1
No known key found for this signature in database
GPG Key ID: 208C6E08C3B718D2

View File

@ -28,7 +28,6 @@ import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineStage; import com.volmit.iris.engine.framework.EngineStage;
import com.volmit.iris.engine.framework.WrongEngineBroException; import com.volmit.iris.engine.framework.WrongEngineBroException;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.context.ChunkContext; import com.volmit.iris.util.context.ChunkContext;
import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.context.IrisContext;
@ -51,6 +50,7 @@ import java.io.IOException;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.function.Consumer; import java.util.function.Consumer;
public class IrisHeadless { public class IrisHeadless {
@ -228,9 +228,9 @@ public class IrisHeadless {
regionThread = null; regionThread = null;
} }
regions.values().forEach(Region::submit); regions.v().forEach(Region::submit);
Iris.info("Waiting for " + loadedChunks.get() + " chunks to unload..."); Iris.info("Waiting for " + loadedChunks.get() + " chunks to unload...");
while (loadedChunks.get() > 0 || !regions.isEmpty()) while (loadedChunks.get() > 0)
J.sleep(1); J.sleep(1);
Iris.info("All chunks unloaded"); Iris.info("All chunks unloaded");
executor.shutdown(); executor.shutdown();
@ -244,9 +244,10 @@ public class IrisHeadless {
private class Region implements Runnable { private class Region implements Runnable {
private final int x, z; private final int x, z;
private final long key; private final long key;
private final KList<SerializableChunk> chunks = new KList<>(1024); private final AtomicReferenceArray<SerializableChunk> chunks = new AtomicReferenceArray<>(1024);
private final AtomicReference<Future<?>> full = new AtomicReference<>(); private final AtomicReference<Future<?>> full = new AtomicReference<>();
private long lastEntry = M.ms(); private transient int size;
private transient long lastEntry = M.ms();
public Region(long key) { public Region(long key) {
this.x = Cache.keyX(key); this.x = Cache.keyX(key);
@ -259,7 +260,11 @@ public class IrisHeadless {
try (IRegion region = storage.getRegion(x, z, false)) { try (IRegion region = storage.getRegion(x, z, false)) {
assert region != null; assert region != null;
for (var chunk : chunks) { for (int i = 0; i < 1024; i++) {
SerializableChunk chunk = chunks.get(i);
if (chunk == null)
continue;
try { try {
region.write(chunk); region.write(chunk);
} catch (Throwable e) { } catch (Throwable e) {
@ -271,26 +276,32 @@ public class IrisHeadless {
} catch (Throwable e) { } catch (Throwable e) {
Iris.error("Failed to load region file " + x + ", " + z); Iris.error("Failed to load region file " + x + ", " + z);
e.printStackTrace(); e.printStackTrace();
loadedChunks.addAndGet(-chunks.size()); loadedChunks.addAndGet(-size);
} }
regions.remove(key);
} }
public synchronized void add(SerializableChunk chunk) { public synchronized void add(SerializableChunk chunk) {
chunks.add(chunk);
lastEntry = M.ms(); lastEntry = M.ms();
if (chunks.size() < 1024) if (chunks.getAndSet(index(chunk.getPos()), chunk) != null)
throw new IllegalStateException("Chunk " + chunk.getPos() + " already exists");
if (++size < 1024)
return; return;
submit(); submit();
} }
public void submit() { public void submit() {
regions.remove(key);
full.getAndUpdate(future -> { full.getAndUpdate(future -> {
if (future != null) return future; if (future != null) return future;
return executor.submit(this); return executor.submit(this);
}); });
} }
private int index(Position2 chunk) {
int x = chunk.getX() & 31;
int z = chunk.getZ() & 31;
return z * 32 + x;
}
} }
private static class CompletingThread extends Thread { private static class CompletingThread extends Thread {