diff --git a/Spigot-Server-Patches/0312-Optimize-Region-File-Cache.patch b/Spigot-Server-Patches/0312-Optimize-Region-File-Cache.patch new file mode 100644 index 000000000..0709758d4 --- /dev/null +++ b/Spigot-Server-Patches/0312-Optimize-Region-File-Cache.patch @@ -0,0 +1,67 @@ +From e979cf5f12f51ca8cea8931026b091f21cc62eb9 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Mon, 23 Jul 2018 23:40:04 -0400 +Subject: [PATCH] Optimize Region File Cache + +CraftBukkit added synchronization to read and write methods. This adds +much more contention on this object for accessing region files, as +the entire read and write of NBT data is now a blocking operation. + +This causes issues when something then simply needs to check if a chunk exists +on the main thread, causing a block... + +However, this synchronization was unnecessary, because there is already +enough synchronization done to keep things safe + +1) Obtaining a Region File: Those methods are still static synchronized. + Meaning we can safely obtain a Region File concurrently. + +2) RegionFile data access: Methods reading and manipulating data from + a region file are also marked synchronized, ensuring that no 2 processes + are reading or writing data at the same time. + +3) Checking a region file for chunkExists: getOffset is also synchronized + ensuring that even if a chunk is currently being written, it will be safe. + +By removing these synchronizations, we reduce the locking to only +when data is being write or read. + +GZIP compression and NBT Buffer creation will no longer be part of the +synchronized context, reducing lock times. + +Ultimately: This brings us back to Vanilla, which has had no indication of region file loss. + +diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java +index 3b8d01ea1..609d6c355 100644 +--- a/src/main/java/net/minecraft/server/RegionFileCache.java ++++ b/src/main/java/net/minecraft/server/RegionFileCache.java +@@ -97,7 +97,7 @@ public class RegionFileCache { + + @Nullable + // CraftBukkit start - call sites hoisted for synchronization +- public static synchronized NBTTagCompound read(File file, int i, int j) throws IOException { ++ public static NBTTagCompound read(File file, int i, int j) throws IOException { // Paper - remove synchronization + RegionFile regionfile = a(file, i, j); + + DataInputStream datainputstream = regionfile.a(i & 31, j & 31); +@@ -110,7 +110,7 @@ public class RegionFileCache { + } + + @Nullable +- public static synchronized void write(File file, int i, int j, NBTTagCompound nbttagcompound) throws IOException { ++ public static void write(File file, int i, int j, NBTTagCompound nbttagcompound) throws IOException { // Paper - remove synchronization + RegionFile regionfile = a(file, i, j); + + DataOutputStream dataoutputstream = regionfile.c(i & 31, j & 31); +@@ -119,7 +119,7 @@ public class RegionFileCache { + } + // CraftBukkit end + +- public static synchronized boolean chunkExists(File file, int i, int j) { ++ public static boolean chunkExists(File file, int i, int j) { // Paper - remove synchronization + RegionFile regionfile = b(file, i, j); + + return regionfile != null ? regionfile.d(i & 31, j & 31) : false; +-- +2.18.0 +