From 7637905de2f88201cea07ae726f98798584c6d0c Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Tue, 10 Aug 2021 07:19:10 -0400 Subject: [PATCH] Safe saving / trimming --- .../com/volmit/iris/util/mantle/Mantle.java | 56 +++++++------------ .../volmit/iris/util/mantle/MantleChunk.java | 22 ++++++++ .../iris/util/mantle/TectonicPlate.java | 26 ++++++++- 3 files changed, 64 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java index 4f917c107..c96c4f5c7 100644 --- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -266,25 +266,26 @@ public class Mantle { unload.clear(); for (Long i : lastUse.keySet()) { - if (M.ms() - lastUse.get(i) >= idleDuration) { - unload.add(i); - } + hyperLock.withLong(i, () -> { + if (M.ms() - lastUse.get(i) >= idleDuration) { + unload.add(i); + } + }); } for (Long i : unload) { - TectonicPlate m = loadedRegions.remove(i); - lastUse.remove(i); - Iris.debug("Unloaded Tectonic Plate " + C.DARK_GREEN + i); + hyperLock.withLong(i, () ->{ + TectonicPlate m = loadedRegions.remove(i); + lastUse.remove(i); - if (m != null) { - ioBurst.lazy(() -> { - try { - m.write(fileForRegion(dataFolder, i)); - } catch (IOException e) { - e.printStackTrace(); - } - }); - } + try { + m.write(fileForRegion(dataFolder, i)); + } catch (IOException e) { + e.printStackTrace(); + } + + Iris.debug("Unloaded Tectonic Plate " + C.DARK_GREEN + Cache.keyX(i) + " " + Cache.keyZ(i)); + }); } } @@ -297,12 +298,13 @@ public class Mantle { * @return the future of a tectonic plate. */ @RegionCoordinates - private CompletableFuture get(int x, int z) { + private synchronized CompletableFuture get(int x, int z) { Long k = key(x, z); TectonicPlate p = loadedRegions.get(k); if(p != null) { + lastUse.put(k, M.ms()); return CompletableFuture.completedFuture(p); } @@ -318,10 +320,7 @@ public class Mantle { if (file.exists()) { try { - FileInputStream fin = new FileInputStream(file); - DataInputStream din = new DataInputStream(fin); - region = new TectonicPlate(worldHeight, din); - din.close(); + region = TectonicPlate.read(worldHeight, file); loadedRegions.put(k, region); Iris.debug("Loaded Tectonic Plate " + C.DARK_GREEN + x + " " + z + C.DARK_AQUA + " " + file.getName()); } catch (Throwable e) { @@ -359,23 +358,6 @@ public class Mantle { } public void saveAll() { - Iris.debug("Saving The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath()); - if (closed.get()) { - throw new RuntimeException("The Mantle is closed"); - } - BurstExecutor b = ioBurst.burst(loadedRegions.size()); - for (Long i : loadedRegions.keySet()) { - b.queue(() -> { - try { - loadedRegions.get(i).write(fileForRegion(dataFolder, i)); - } catch (IOException e) { - e.printStackTrace(); - } - }); - } - - b.complete(); - Iris.debug("The Mantle has Saved " + C.DARK_AQUA + dataFolder.getAbsolutePath()); } } diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java index f677550d5..fa8712dde 100644 --- a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java +++ b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java @@ -163,6 +163,8 @@ public class MantleChunk { } for (int i = 0; i < sections.length(); i++) { + trimSlice(i); + if (exists(i)) { dos.writeBoolean(true); Matter matter = get(i); @@ -173,6 +175,26 @@ public class MantleChunk { } } + private void trimSlice(int i) { + if(exists(i)) + { + Matter m = get(i); + + if(m.getSliceMap().isEmpty()) + { + sections.set(i, null); + } + + else{ + m.trimSlices(); + if(m.getSliceMap().isEmpty()) + { + sections.set(i, null); + } + } + } + } + public void iterate(Class type, Consumer4 iterator) { for(int i = 0; i < sections.length(); i++) { diff --git a/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java b/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java index cbaa79549..76f390d7f 100644 --- a/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java +++ b/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java @@ -21,9 +21,12 @@ package com.volmit.iris.util.mantle; import com.volmit.iris.Iris; import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.format.C; +import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; import java.io.*; import java.util.concurrent.atomic.AtomicReferenceArray; +import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; /** @@ -62,6 +65,16 @@ public class TectonicPlate { } } + public static TectonicPlate read(int worldHeight, File file) throws IOException, ClassNotFoundException { + FileInputStream fin = new FileInputStream(file); + GZIPInputStream gzi = new GZIPInputStream(fin); + DataInputStream din = new DataInputStream(gzi); + TectonicPlate p = new TectonicPlate(worldHeight, din); + din.close(); + + return p; + } + /** * Check if a chunk exists in this plate or not (same as get(x, z) != null) * @@ -137,11 +150,13 @@ public class TectonicPlate { * @throws IOException shit happens */ public void write(File file) throws IOException { + PrecisionStopwatch p = PrecisionStopwatch.start(); FileOutputStream fos = new FileOutputStream(file); - DataOutputStream dos = new DataOutputStream(fos); + GZIPOutputStream gzo = new GZIPOutputStream(fos); + DataOutputStream dos = new DataOutputStream(gzo); write(dos); dos.close(); - Iris.debug("Saved Tectonic Plate " + C.DARK_GREEN + file.getName().split("\\Q.\\E")[0]); + Iris.debug("Saved Tectonic Plate " + C.DARK_GREEN + file.getName().split("\\Q.\\E")[0] + C.RED + " in " + Form.duration(p.getMilliseconds(), 2)); } /** @@ -153,11 +168,16 @@ public class TectonicPlate { public void write(DataOutputStream dos) throws IOException { for (int i = 0; i < chunks.length(); i++) { MantleChunk chunk = chunks.get(i); - dos.writeBoolean(chunk != null); if (chunk != null) { + dos.writeBoolean(true); chunk.write(dos); } + + else + { + dos.writeBoolean(false); + } } } }