Safe saving / trimming

This commit is contained in:
Daniel Mills 2021-08-10 07:19:10 -04:00
parent ec780b7b93
commit 7637905de2
3 changed files with 64 additions and 40 deletions

View File

@ -266,27 +266,28 @@ public class Mantle {
unload.clear(); unload.clear();
for (Long i : lastUse.keySet()) { for (Long i : lastUse.keySet()) {
hyperLock.withLong(i, () -> {
if (M.ms() - lastUse.get(i) >= idleDuration) { if (M.ms() - lastUse.get(i) >= idleDuration) {
unload.add(i); unload.add(i);
} }
});
} }
for (Long i : unload) { for (Long i : unload) {
hyperLock.withLong(i, () ->{
TectonicPlate m = loadedRegions.remove(i); TectonicPlate m = loadedRegions.remove(i);
lastUse.remove(i); lastUse.remove(i);
Iris.debug("Unloaded Tectonic Plate " + C.DARK_GREEN + i);
if (m != null) {
ioBurst.lazy(() -> {
try { try {
m.write(fileForRegion(dataFolder, i)); m.write(fileForRegion(dataFolder, i));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
Iris.debug("Unloaded Tectonic Plate " + C.DARK_GREEN + Cache.keyX(i) + " " + Cache.keyZ(i));
}); });
} }
} }
}
/** /**
* This retreives a future of the Tectonic Plate at the given coordinates. * This retreives a future of the Tectonic Plate at the given coordinates.
@ -297,12 +298,13 @@ public class Mantle {
* @return the future of a tectonic plate. * @return the future of a tectonic plate.
*/ */
@RegionCoordinates @RegionCoordinates
private CompletableFuture<TectonicPlate> get(int x, int z) { private synchronized CompletableFuture<TectonicPlate> get(int x, int z) {
Long k = key(x, z); Long k = key(x, z);
TectonicPlate p = loadedRegions.get(k); TectonicPlate p = loadedRegions.get(k);
if(p != null) if(p != null)
{ {
lastUse.put(k, M.ms());
return CompletableFuture.completedFuture(p); return CompletableFuture.completedFuture(p);
} }
@ -318,10 +320,7 @@ public class Mantle {
if (file.exists()) { if (file.exists()) {
try { try {
FileInputStream fin = new FileInputStream(file); region = TectonicPlate.read(worldHeight, file);
DataInputStream din = new DataInputStream(fin);
region = new TectonicPlate(worldHeight, din);
din.close();
loadedRegions.put(k, region); loadedRegions.put(k, region);
Iris.debug("Loaded Tectonic Plate " + C.DARK_GREEN + x + " " + z + C.DARK_AQUA + " " + file.getName()); Iris.debug("Loaded Tectonic Plate " + C.DARK_GREEN + x + " " + z + C.DARK_AQUA + " " + file.getName());
} catch (Throwable e) { } catch (Throwable e) {
@ -359,23 +358,6 @@ public class Mantle {
} }
public void saveAll() { 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());
} }
} }

View File

@ -163,6 +163,8 @@ public class MantleChunk {
} }
for (int i = 0; i < sections.length(); i++) { for (int i = 0; i < sections.length(); i++) {
trimSlice(i);
if (exists(i)) { if (exists(i)) {
dos.writeBoolean(true); dos.writeBoolean(true);
Matter matter = get(i); 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 <T> void iterate(Class<T> type, Consumer4<Integer, Integer, Integer,T> iterator) { public <T> void iterate(Class<T> type, Consumer4<Integer, Integer, Integer,T> iterator) {
for(int i = 0; i < sections.length(); i++) for(int i = 0; i < sections.length(); i++)
{ {

View File

@ -21,9 +21,12 @@ package com.volmit.iris.util.mantle;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.format.C; 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.io.*;
import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream; 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) * 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 * @throws IOException shit happens
*/ */
public void write(File file) throws IOException { public void write(File file) throws IOException {
PrecisionStopwatch p = PrecisionStopwatch.start();
FileOutputStream fos = new FileOutputStream(file); FileOutputStream fos = new FileOutputStream(file);
DataOutputStream dos = new DataOutputStream(fos); GZIPOutputStream gzo = new GZIPOutputStream(fos);
DataOutputStream dos = new DataOutputStream(gzo);
write(dos); write(dos);
dos.close(); 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 { public void write(DataOutputStream dos) throws IOException {
for (int i = 0; i < chunks.length(); i++) { for (int i = 0; i < chunks.length(); i++) {
MantleChunk chunk = chunks.get(i); MantleChunk chunk = chunks.get(i);
dos.writeBoolean(chunk != null);
if (chunk != null) { if (chunk != null) {
dos.writeBoolean(true);
chunk.write(dos); chunk.write(dos);
} }
else
{
dos.writeBoolean(false);
}
} }
} }
} }