diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/cache/PregenCacheImpl.java b/core/src/main/java/com/volmit/iris/core/pregenerator/cache/PregenCacheImpl.java index bf48e06e9..c3404eda5 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/cache/PregenCacheImpl.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/cache/PregenCacheImpl.java @@ -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(); diff --git a/core/src/main/java/com/volmit/iris/core/service/GlobalCacheSVC.java b/core/src/main/java/com/volmit/iris/core/service/GlobalCacheSVC.java index 32d6af184..e8c194974 100644 --- a/core/src/main/java/com/volmit/iris/core/service/GlobalCacheSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/GlobalCacheSVC.java @@ -23,9 +23,11 @@ public class GlobalCacheSVC implements IrisService { private static final Cache REFERENCE_CACHE = Caffeine.newBuilder().weakValues().build(); private final KMap 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(); } } diff --git a/core/src/main/java/com/volmit/iris/util/collection/KMap.java b/core/src/main/java/com/volmit/iris/util/collection/KMap.java index 01baab32b..4a7f938e0 100644 --- a/core/src/main/java/com/volmit/iris/util/collection/KMap.java +++ b/core/src/main/java/com/volmit/iris/util/collection/KMap.java @@ -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 extends ConcurrentHashMap { return g; } + public KMap qclear(BiConsumer action) { + final Iterator> it = entrySet().iterator(); + while (it.hasNext()) { + final Map.Entry entry = it.next(); + it.remove(); + try { + action.accept(entry.getKey(), entry.getValue()); + } catch (Throwable e) { + Iris.reportError(e); + } + } + return this; + } + /** * Create a keypair queue * diff --git a/core/src/main/java/com/volmit/iris/util/io/IO.java b/core/src/main/java/com/volmit/iris/util/io/IO.java index 554058244..281f08096 100644 --- a/core/src/main/java/com/volmit/iris/util/io/IO.java +++ b/core/src/main/java/com/volmit/iris/util/io/IO.java @@ -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 void write(File file, IOFunction builder, IOConsumer 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(); + } + } }