return noop pregen cache when the service is disabled and write pregen cache to temp file first then replace real one

This commit is contained in:
Julian Krings 2025-06-06 17:24:23 +02:00
parent 2ee22db072
commit 52f87befa2
No known key found for this signature in database
GPG Key ID: 208C6E08C3B718D2
4 changed files with 43 additions and 7 deletions

View File

@ -7,6 +7,7 @@ import com.volmit.iris.Iris;
import com.volmit.iris.util.data.Varint;
import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.documentation.RegionCoordinates;
import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.parallel.HyperLock;
import lombok.RequiredArgsConstructor;
import net.jpountz.lz4.LZ4BlockInputStream;
@ -82,8 +83,8 @@ class PregenCacheImpl implements PregenCache {
hyperLock.lock(plate.pos.x, plate.pos.z);
try {
File file = fileForPlate(plate.pos);
try (var out = new DataOutputStream(new LZ4BlockOutputStream(new FileOutputStream(file)))) {
plate.write(out);
try {
IO.write(file, out -> new DataOutputStream(new LZ4BlockOutputStream(out)), plate::write);
} catch (IOException e) {
Iris.error("Failed to write pregen cache " + file);
e.printStackTrace();

View File

@ -23,9 +23,11 @@ public class GlobalCacheSVC implements IrisService {
private static final Cache<String, PregenCache> REFERENCE_CACHE = Caffeine.newBuilder().weakValues().build();
private final KMap<String, PregenCache> globalCache = new KMap<>();
private transient boolean lastState;
private static boolean disabled = true;
@Override
public void onEnable() {
disabled = false;
lastState = !IrisSettings.get().getWorld().isGlobalPregenCache();
if (lastState) return;
Bukkit.getWorlds().forEach(this::createCache);
@ -33,7 +35,8 @@ public class GlobalCacheSVC implements IrisService {
@Override
public void onDisable() {
globalCache.values().forEach(PregenCache::write);
disabled = true;
globalCache.qclear((world, cache) -> cache.write());
}
@Nullable
@ -99,6 +102,7 @@ public class GlobalCacheSVC implements IrisService {
}
private static PregenCache createDefault0(String worldName) {
if (disabled) return PregenCache.EMPTY;
return PregenCache.create(new File(Bukkit.getWorldContainer(), String.join(File.separator, worldName, "iris", "pregen"))).sync();
}
}

View File

@ -23,11 +23,9 @@ import com.volmit.iris.util.function.Consumer2;
import com.volmit.iris.util.function.Consumer3;
import com.volmit.iris.util.scheduling.Queue;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Map;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
@SuppressWarnings("ALL")
@ -373,6 +371,20 @@ public class KMap<K, V> extends ConcurrentHashMap<K, V> {
return g;
}
public KMap<K, V> qclear(BiConsumer<K, V> action) {
final Iterator<Map.Entry<K, V>> it = entrySet().iterator();
while (it.hasNext()) {
final Map.Entry<K, V> entry = it.next();
it.remove();
try {
action.accept(entry.getKey(), entry.getValue());
} catch (Throwable e) {
Iris.reportError(e);
}
}
return this;
}
/**
* Create a keypair queue
*

View File

@ -24,9 +24,13 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.volmit.iris.Iris;
import com.volmit.iris.util.format.Form;
import org.apache.commons.io.function.IOConsumer;
import org.apache.commons.io.function.IOFunction;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@ -1638,4 +1642,19 @@ public class IO {
int ch2 = input2.read();
return (ch2 == -1);
}
public static <T extends OutputStream> void write(File file, IOFunction<FileOutputStream, T> builder, IOConsumer<T> action) throws IOException {
File dir = new File(file.getParentFile(), ".tmp");
dir.mkdirs();
dir.deleteOnExit();
File temp = File.createTempFile("iris",".bin", dir);
try {
try (var out = builder.apply(new FileOutputStream(temp))) {
action.accept(out);
}
Files.move(temp.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
} finally {
temp.delete();
}
}
}