PaperSpigot-Parent/CraftBukkit-Patches/0071-Improve-AutoSave-Mechanism.patch
Zach Brown c9daa16dac Update from upstream SpigotMC
72d33338f08
2a70ece9ab2 [M]
abcf7aa4a40
9a88a38258c [M]
8dc4297e34f
2014-12-05 21:33:40 -06:00

75 lines
3.4 KiB
Diff

From 1726fd02fac28834745b15aac24be4c8f050de5b Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
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 e664e55..1412616 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -917,7 +917,7 @@ public class Chunk {
if (this.r && this.world.getTime() != this.lastSaved || this.q) {
return true;
}
- } else if (this.r && this.world.getTime() >= this.lastSaved + 600L) {
+ } else if (this.r && 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/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 7ce37c0..4a2f084 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -623,7 +623,17 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
SpigotTimings.worldSaveTimer.startTiming(); // Spigot
this.methodProfiler.a("save");
this.v.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 : worlds) {
+ world.getWorld().save(false);
+ }
+ server.playerCommandState = false;
+ // this.saveChunks(true);
+ // Spigot End
this.methodProfiler.b();
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 2545b38..d61c1de 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -688,12 +688,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.1.0