2018-10-05 03:18:46 +00:00
|
|
|
From dddfa3385a6f08eb4bba4dcaf6ef11570db9c0f5 Mon Sep 17 00:00:00 2001
|
2018-07-24 03:50:09 +00:00
|
|
|
From: Aikar <aikar@aikar.co>
|
|
|
|
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
|
2018-08-26 18:11:49 +00:00
|
|
|
index c0ab543b91..15666325ea 100644
|
2018-07-24 03:50:09 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/RegionFileCache.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/RegionFileCache.java
|
2018-08-26 18:11:49 +00:00
|
|
|
@@ -99,7 +99,7 @@ public class RegionFileCache {
|
2018-07-24 03:50:09 +00:00
|
|
|
|
|
|
|
@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);
|
2018-08-26 18:11:49 +00:00
|
|
|
@@ -112,7 +112,7 @@ public class RegionFileCache {
|
2018-07-24 03:50:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
- public static synchronized void write(File file, int i, int j, NBTTagCompound nbttagcompound) throws IOException {
|
2018-08-26 18:11:49 +00:00
|
|
|
+ public static void write(File file, int i, int j, NBTTagCompound nbttagcompound) throws IOException {
|
|
|
|
int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper
|
2018-07-24 03:50:09 +00:00
|
|
|
RegionFile regionfile = a(file, i, j);
|
|
|
|
|
2018-08-26 18:11:49 +00:00
|
|
|
@@ -138,7 +138,7 @@ public class RegionFileCache {
|
|
|
|
// Paper end
|
2018-07-24 03:50:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- 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;
|
|
|
|
--
|
2018-09-27 02:35:42 +00:00
|
|
|
2.19.0
|
2018-07-24 03:50:09 +00:00
|
|
|
|