From 39437823176924dffde3fcefcb3d80de3d543769 Mon Sep 17 00:00:00 2001 From: Johny Muffin Date: Tue, 6 Aug 2024 13:06:42 +1000 Subject: [PATCH] Automatic bench-marker and improved usage information --- .gitignore | 4 ++ pom.xml | 49 ++++++++++++-- src/main/java/AutomaticBenchmarker.java | 64 +++++++++++++++++++ src/main/java/DualOutputStream.java | 43 +++++++++++++ .../world/level/storage/AnvilConverter.java | 11 +++- 5 files changed, 164 insertions(+), 7 deletions(-) create mode 100644 src/main/java/AutomaticBenchmarker.java create mode 100644 src/main/java/DualOutputStream.java diff --git a/.gitignore b/.gitignore index 5a0543a..7951a6f 100644 --- a/.gitignore +++ b/.gitignore @@ -220,3 +220,7 @@ modules.xml hs_err_pid* # End of https://www.gitignore.io/api/java,intellij,intellij+all,intellij+iml + +target/ + +*.lck diff --git a/pom.xml b/pom.xml index 1c055f3..68fb0ac 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,48 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example - Server - 1.0-SNAPSHOT - \ No newline at end of file + com.johnymuffin + mcregion-to-anvil-converter + 1.0.0 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + net.minecraft.world.level.storage.AnvilConverter + + + + + + + + + + + + + diff --git a/src/main/java/AutomaticBenchmarker.java b/src/main/java/AutomaticBenchmarker.java new file mode 100644 index 0000000..2d800ec --- /dev/null +++ b/src/main/java/AutomaticBenchmarker.java @@ -0,0 +1,64 @@ +import net.minecraft.world.level.storage.AnvilConverter; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.logging.*; + +public class AutomaticBenchmarker { + + private static final Logger logger = Logger.getLogger(AutomaticBenchmarker.class.getName()); + + public static void main(String[] args) { + setupLogger(); + + // Notice: This program performs automatic benchmarking of the AnvilConverter application. + logger.info("Starting automatic benchmarking of the AnvilConverter application."); + + // Fake arguments for the AnvilConverter application + String baseFolderPath = "E:\\RetroMC-1\\"; + String worldName = "retromc"; + int[] threadCounts = {32, 16, 8, 4, 2, 1, 0}; // 0 runs the converter sequentially on the main thread + + for (int numThreads : threadCounts) { + logger.info("Running benchmark with " + numThreads + " threads."); + AnvilConverter.main(new String[]{baseFolderPath, worldName, String.valueOf(numThreads)}); + + // Cleanup JVM + System.gc(); + + // Sleep for 1 minute to allow the JVM to cleanup + try { + Thread.sleep(60000); + } catch (InterruptedException e) { + logger.log(Level.WARNING, "Thread interrupted while sleeping", e); + } + } + } + + private static void setupLogger() { + try { + // Create a file handler that writes log record to a file called benchmark.log + FileHandler fileHandler = new FileHandler("benchmark.log", true); + fileHandler.setFormatter(new SimpleFormatter()); + + // Add the file handler to the logger + logger.addHandler(fileHandler); + + // Set the logger level to INFO + logger.setLevel(Level.INFO); + + // Also log to the console + ConsoleHandler consoleHandler = new ConsoleHandler(); + consoleHandler.setFormatter(new SimpleFormatter()); + logger.addHandler(consoleHandler); + + // Redirect System.out and System.err to logger + PrintStream logStream = new PrintStream(new DualOutputStream(System.out, new FileOutputStream("benchmark.log", true))); + System.setOut(logStream); + System.setErr(logStream); + + } catch (IOException e) { + logger.log(Level.SEVERE, "Failed to setup logger", e); + } + } +} diff --git a/src/main/java/DualOutputStream.java b/src/main/java/DualOutputStream.java new file mode 100644 index 0000000..b8774b5 --- /dev/null +++ b/src/main/java/DualOutputStream.java @@ -0,0 +1,43 @@ +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.IOException; + +public class DualOutputStream extends OutputStream { + private final OutputStream outputStream1; + private final OutputStream outputStream2; + + public DualOutputStream(OutputStream outputStream1, OutputStream outputStream2) { + this.outputStream1 = outputStream1; + this.outputStream2 = outputStream2; + } + + @Override + public void write(int b) throws IOException { + outputStream1.write(b); + outputStream2.write(b); + } + + @Override + public void write(byte[] b) throws IOException { + outputStream1.write(b); + outputStream2.write(b); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + outputStream1.write(b, off, len); + outputStream2.write(b, off, len); + } + + @Override + public void flush() throws IOException { + outputStream1.flush(); + outputStream2.flush(); + } + + @Override + public void close() throws IOException { + outputStream1.close(); + outputStream2.close(); + } +} diff --git a/src/main/java/net/minecraft/world/level/storage/AnvilConverter.java b/src/main/java/net/minecraft/world/level/storage/AnvilConverter.java index b71bea5..af3d539 100644 --- a/src/main/java/net/minecraft/world/level/storage/AnvilConverter.java +++ b/src/main/java/net/minecraft/world/level/storage/AnvilConverter.java @@ -133,15 +133,20 @@ public void progressStage(String string) { private static void printUsageAndExit() { System.out.println("Map converter for Minecraft, from format \"McRegion\" to \"Anvil\". (c) Mojang AB 2012"); - System.out.println(""); + System.out.println("Forked by RhysB to include multi-threaded conversion support."); + System.out.println(); System.out.println("Usage:"); - System.out.println("\tjava -jar AnvilConverter.jar "); + System.out.println("\tjava -jar AnvilConverter.jar [thread count]"); System.out.println("Where:"); System.out.println("\t\tThe full path to the folder containing Minecraft world folders"); System.out.println("\t\tThe folder name of the Minecraft world to be converted"); + System.out.println("\t[thread count]\t(Optional) Number of threads to use for conversion. Defaults to 1 if not specified."); System.out.println("Example:"); - System.out.println("\tjava -jar AnvilConverter.jar /home/jeb_/minecraft world"); + System.out.println("\tjava -jar AnvilConverter.jar /home/jeb_/minecraft world - Convert world using 1 thread"); + System.out.println("\tjava -jar AnvilConverter.jar /home/jeb_/minecraft world 0 - Convert world sequentially on the main thread"); + System.out.println("\tjava -jar AnvilConverter.jar /home/jeb_/minecraft world 4 - Convert world using 4 threads"); System.exit(1); } + }