From e490d853f0abf1b3db76b2a1758d317df86fba56 Mon Sep 17 00:00:00 2001 From: Poweruser_rs Date: Fri, 29 Jan 2016 01:38:46 +0100 Subject: [PATCH] Cache and async save player data diff --git a/src/main/java/net/frozenorb/PlayerDataCache.java b/src/main/java/net/frozenorb/PlayerDataCache.java new file mode 100644 index 000000000..1f4b0337f --- /dev/null +++ b/src/main/java/net/frozenorb/PlayerDataCache.java @@ -0,0 +1,20 @@ +package net.frozenorb; + +import java.util.LinkedHashMap; +import java.util.Map; + +import net.minecraft.server.MinecraftServer; + +public class PlayerDataCache extends LinkedHashMap{ + + private static final long serialVersionUID = 5272337123874421616L; + + public PlayerDataCache() { + super(100, 0.75F, true); + } + + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return this.size() > MinecraftServer.getServer().getPlayerList().getPlayerCount(); + } +} diff --git a/src/main/java/net/frozenorb/PlayerDataSaveJob.java b/src/main/java/net/frozenorb/PlayerDataSaveJob.java new file mode 100644 index 000000000..b813b5009 --- /dev/null +++ b/src/main/java/net/frozenorb/PlayerDataSaveJob.java @@ -0,0 +1,45 @@ +package net.frozenorb; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import net.minecraft.server.NBTCompressedStreamTools; +import net.minecraft.server.NBTTagCompound; + +public class PlayerDataSaveJob implements Runnable { + + private File target; + private NBTTagCompound data; + + public PlayerDataSaveJob (File target, NBTTagCompound data) { + this.target = target; + this.data = data; + } + + @Override + public void run() { + File temp = new File(this.target.getPath() + ".tmp"); + FileOutputStream fileoutputstream = null; + try { + fileoutputstream = new FileOutputStream(temp); + NBTCompressedStreamTools.a(this.data, (OutputStream) fileoutputstream); + if (this.target.exists()) { + this.target.delete(); + } + temp.renameTo(this.target); + } catch (Exception e) { + System.out.println(e.toString()); + e.printStackTrace(); + } finally { + if(fileoutputstream != null) { + try { + fileoutputstream.close(); + } catch (IOException e) { } + } + } + this.target = null; + this.data = null; + } +} diff --git a/src/main/java/net/frozenorb/ThreadingManager.java b/src/main/java/net/frozenorb/ThreadingManager.java index ed1dfbbc2..8edfe726a 100644 --- a/src/main/java/net/frozenorb/ThreadingManager.java +++ b/src/main/java/net/frozenorb/ThreadingManager.java @@ -41,6 +41,10 @@ public class ThreadingManager { } } + public static void saveNBTPlayerDataStatic(PlayerDataSaveJob savejob) { + instance.nbtFileService.execute(savejob); + } + public static void saveNBTFileStatic(NBTTagCompound compound, File file) { instance.saveNBTFile(compound, file); } diff --git a/src/main/java/net/minecraft/server/WorldNBTStorage.java b/src/main/java/net/minecraft/server/WorldNBTStorage.java index 141248e3e..93135a70c 100644 --- a/src/main/java/net/minecraft/server/WorldNBTStorage.java +++ b/src/main/java/net/minecraft/server/WorldNBTStorage.java @@ -18,6 +18,12 @@ import java.util.UUID; import org.bukkit.craftbukkit.entity.CraftPlayer; // CraftBukkit end +// Poweruser start +import net.frozenorb.PlayerDataCache; +import net.frozenorb.PlayerDataSaveJob; +import net.frozenorb.ThreadingManager; +// Poweruser end + public class WorldNBTStorage implements IDataManager, IPlayerFileData { private static final Logger a = LogManager.getLogger(); @@ -27,6 +33,7 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { private final long sessionId = MinecraftServer.ar(); private final String f; private UUID uuid = null; // CraftBukkit + private PlayerDataCache dataCache = new PlayerDataCache(); // Poweruser public WorldNBTStorage(File file1, String s, boolean flag) { this.baseDir = new File(file1, s); @@ -177,15 +184,14 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { NBTTagCompound nbttagcompound = new NBTTagCompound(); entityhuman.e(nbttagcompound); - File file1 = new File(this.playerDir, entityhuman.getUniqueID().toString() + ".dat.tmp"); - File file2 = new File(this.playerDir, entityhuman.getUniqueID().toString() + ".dat"); - NBTCompressedStreamTools.a(nbttagcompound, (OutputStream) (new FileOutputStream(file1))); - if (file2.exists()) { - file2.delete(); + // Poweruser start + File file2 = new File(this.playerDir, entityhuman.getUniqueID().toString() + ".dat"); + synchronized(this.dataCache) { + this.dataCache.put(file2, nbttagcompound); } - - file1.renameTo(file2); + ThreadingManager.saveNBTPlayerDataStatic(new PlayerDataSaveJob(file2, nbttagcompound)); + // Poweruser end } catch (Exception exception) { a.warn("Failed to save player data for " + entityhuman.getName()); } @@ -198,9 +204,21 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { File file1 = new File(this.playerDir, entityhuman.getUniqueID().toString() + ".dat"); // Spigot Start boolean usingWrongFile = false; - if ( !file1.exists() ) + + // Poweruser start + NBTTagCompound playerdata = null; + synchronized(this.dataCache) { + playerdata = this.dataCache.get(file1); + } + if ( !file1.exists() && playerdata == null) + // Poweruser end { file1 = new File( this.playerDir, UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + entityhuman.getName() ).getBytes( "UTF-8" ) ).toString() + ".dat"); + // Poweruser start + synchronized(this.dataCache) { + playerdata = this.dataCache.get(file1); + } + // Poweruser end if ( file1.exists() ) { usingWrongFile = true; @@ -209,6 +227,11 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { } // Spigot End + // Poweruser start + if (playerdata != null) { + nbttagcompound = playerdata; + } else + // Poweruser end if (file1.exists() && file1.isFile()) { nbttagcompound = NBTCompressedStreamTools.a((InputStream) (new FileInputStream(file1))); } -- 2.13.3