From 4b5902de920d1b9fe71b89538fa5c8cccde07d48 Mon Sep 17 00:00:00 2001
From: Antony Riley <antony@cyberiantiger.org>
Date: Tue, 29 Mar 2016 08:27:14 +0300
Subject: [PATCH] Sanitise RegionFileCache and make cache size configurable.

---
 ...egionFileCache-and-make-configurable.patch | 79 +++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100644 Spigot-Server-Patches/Sanitise-RegionFileCache-and-make-configurable.patch

diff --git a/Spigot-Server-Patches/Sanitise-RegionFileCache-and-make-configurable.patch b/Spigot-Server-Patches/Sanitise-RegionFileCache-and-make-configurable.patch
new file mode 100644
index 0000000000..7e8d422786
--- /dev/null
+++ b/Spigot-Server-Patches/Sanitise-RegionFileCache-and-make-configurable.patch
@@ -0,0 +1,79 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Antony Riley <antony@cyberiantiger.org>
+Date: Tue, 29 Mar 2016 08:22:55 +0300
+Subject: [PATCH] Sanitise RegionFileCache and make configurable.
+
+RegionFileCache prior to this patch would close every single open region
+file upon reaching a size of 256.
+This patch modifies that behaviour so it closes the the least recently
+used RegionFile.
+The implementation uses a LinkedHashMap as an LRU cache (modified from HashMap).
+The maximum size of the RegionFileCache is also made configurable.
+
+diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
++++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
+@@ -0,0 +0,0 @@ public class PaperConfig {
+     public static void healthDeath() {
+         setHealthBeforeDeathEvent = getBoolean("settings.set-health-before-death-event", false);
+     }
++
++    public static int regionFileCacheSize = 256;
++    private static void regionFileCacheSize() {
++        regionFileCacheSize = getInt("settings.region-file-cache-size", 256);
++    }
+ }
+diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/RegionFileCache.java
++++ b/src/main/java/net/minecraft/server/RegionFileCache.java
+@@ -0,0 +0,0 @@ import java.io.File;
+ import java.io.IOException;
+ import java.util.Iterator;
+ import java.util.Map;
++import com.destroystokyo.paper.PaperConfig; // Paper
++import java.util.LinkedHashMap; // Paper
+ 
+ public class RegionFileCache {
+ 
+-    public static final Map<File, RegionFile> a = Maps.newHashMap(); // Spigot - private -> public
++    public static final Map<File, RegionFile> a = new LinkedHashMap(PaperConfig.regionFileCacheSize, 0.75f, true); // Spigot - private -> public, Paper - HashMap -> LinkedHashMap
+ 
+     // Paper start
+     public static synchronized RegionFile a(File file, int i, int j) {
+@@ -0,0 +0,0 @@ public class RegionFileCache {
+                 file1.mkdirs();
+             }
+ 
+-            if (RegionFileCache.a.size() >= 256) {
+-                a();
++            if (RegionFileCache.a.size() >= PaperConfig.regionFileCacheSize) { // Paper
++                trimCache(); // Paper
+             }
+ 
+             RegionFile regionfile1 = new RegionFile(file2);
+@@ -0,0 +0,0 @@ public class RegionFileCache {
+         }
+     }
+ 
++    // Paper Start
++    private static synchronized void trimCache() {
++        Iterator<Map.Entry<File, RegionFile>> itr = RegionFileCache.a.entrySet().iterator();
++        int count = RegionFileCache.a.size() - PaperConfig.regionFileCacheSize;
++        while (count-- >= 0 && itr.hasNext()) {
++            try {
++                itr.next().getValue().c();
++            } catch (IOException ioexception) {
++                ioexception.printStackTrace();
++                ServerInternalException.reportInternalException(ioexception);
++            }
++            itr.remove();
++        }
++    }
++    // Paper End
++
+     public static synchronized void a() {
+         Iterator iterator = RegionFileCache.a.values().iterator();
+ 
+--
\ No newline at end of file