From 28ff5397b65ba7ac203639578e4c1bddeb2f7395 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 12 Jan 2014 21:07:18 +1100 Subject: [PATCH] Improve AutoSave Mechanism The problem here is that MinecraftServer.save(..), will attempt to sleep whilst all pending chunks are written to disk. however due to various and complicated bugs, it will wait for an incorrect amount of chunks, which may cause it to sleep for an overly long amount of time. Instead we will mimic the save-all command in its behaviour, which is both safe and performant. Also, only save modified chunks, or chunks with entities after 4 auto save passes diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java index 05a43083e..5caef447a 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -920,7 +920,7 @@ public class Chunk implements IChunkAccess { if (this.v && this.world.getTime() != this.lastSaved || this.x) { return true; } - } else if (this.v && this.world.getTime() >= this.lastSaved + 600L) { + } else if (this.v && this.world.getTime() >= this.lastSaved + MinecraftServer.getServer().autosavePeriod * 4) { // Spigot - Only save if we've passed 2 auto save intervals without modification return true; } diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java index d9d37b94b..1da14aa17 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -235,7 +235,7 @@ public class ChunkProviderServer implements IChunkProvider { this.saveChunk(chunk); chunk.a(false); ++i; - if (i == 24 && !flag) { + if (i == 24 && !flag && false) { // Spigot return false; } } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 2de4c5628..f30288040 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -821,7 +821,17 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati SpigotTimings.worldSaveTimer.startTiming(); // Spigot this.methodProfiler.a("save"); this.s.savePlayers(); - this.saveChunks(true); + // Spigot Start + // We replace this with saving each individual world as this.saveChunks(...) is broken, + // and causes the main thread to sleep for random amounts of time depending on chunk activity + // Also pass flag to only save modified chunks + server.playerCommandState = true; + for (World world : getWorlds()) { + world.getWorld().save(false); + } + server.playerCommandState = false; + // this.saveChunks(true); + // Spigot End this.methodProfiler.e(); SpigotTimings.worldSaveTimer.stopTiming(); // Spigot } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 9d5f7c879..225d25a9f 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -716,12 +716,17 @@ public class CraftWorld implements World { } public void save() { + // Spigot start + save(true); + } + public void save(boolean forceSave) { + // Spigot end this.server.checkSaveState(); try { boolean oldSave = world.savingDisabled; world.savingDisabled = false; - world.save(true, null); + world.save(forceSave, null); // Spigot world.savingDisabled = oldSave; } catch (ExceptionWorldConflict ex) { -- 2.17.1