From bcf9aacd3bdcada594d20724a34ddd53294d12d5 Mon Sep 17 00:00:00 2001 From: vemacs Date: Thu, 25 Jun 2015 19:41:41 -0400 Subject: [PATCH] [Somewhat tested] Implement asynchronous save operations and cached read operations --- .../drtshock/playervaults/PlayerVaults.java | 9 +- .../listeners/VaultPreloadListener.java | 32 ++++++ .../vaultmanagement/UUIDVaultManager.java | 105 ++++++++++++++---- 3 files changed, 118 insertions(+), 28 deletions(-) create mode 100644 src/main/java/com/drtshock/playervaults/listeners/VaultPreloadListener.java diff --git a/src/main/java/com/drtshock/playervaults/PlayerVaults.java b/src/main/java/com/drtshock/playervaults/PlayerVaults.java index 17c641f..f208409 100644 --- a/src/main/java/com/drtshock/playervaults/PlayerVaults.java +++ b/src/main/java/com/drtshock/playervaults/PlayerVaults.java @@ -18,6 +18,7 @@ package com.drtshock.playervaults; import com.drtshock.playervaults.commands.*; import com.drtshock.playervaults.listeners.Listeners; +import com.drtshock.playervaults.listeners.VaultPreloadListener; import com.drtshock.playervaults.tasks.Cleanup; import com.drtshock.playervaults.tasks.UUIDConversion; import com.drtshock.playervaults.util.Lang; @@ -72,6 +73,7 @@ public class PlayerVaults extends JavaPlugin { loadLang(); new UUIDVaultManager(); getServer().getPluginManager().registerEvents(new Listeners(this), this); + getServer().getPluginManager().registerEvents(new VaultPreloadListener(), this); this.backupsEnabled = this.getConfig().getBoolean("backups.enabled", true); loadSigns(); checkUpdate(); @@ -103,12 +105,7 @@ public class PlayerVaults extends JavaPlugin { Inventory inventory = player.getOpenInventory().getTopInventory(); if (inventory.getViewers().size() == 1) { VaultViewInfo info = this.inVault.get(player.getName()); - try { - UUIDVaultManager.getInstance().saveVault(inventory, player.getUniqueId(), info.getNumber()); - } catch (IOException e) { - // ignore - } - + UUIDVaultManager.getInstance().saveVault(inventory, player.getUniqueId(), info.getNumber(), false); this.openInventories.remove(info.toString()); } diff --git a/src/main/java/com/drtshock/playervaults/listeners/VaultPreloadListener.java b/src/main/java/com/drtshock/playervaults/listeners/VaultPreloadListener.java new file mode 100644 index 0000000..8793ee0 --- /dev/null +++ b/src/main/java/com/drtshock/playervaults/listeners/VaultPreloadListener.java @@ -0,0 +1,32 @@ +package com.drtshock.playervaults.listeners; + +import com.drtshock.playervaults.PlayerVaults; +import com.drtshock.playervaults.vaultmanagement.UUIDVaultManager; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.UUID; + +public class VaultPreloadListener implements Listener { + UUIDVaultManager vm = UUIDVaultManager.getInstance(); + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerJoin(PlayerJoinEvent event) { + final UUID uuid = event.getPlayer().getUniqueId(); + new BukkitRunnable() { + @Override + public void run() { + vm.cachePlayerVaultFile(uuid); + } + }.runTaskAsynchronously(PlayerVaults.getInstance()); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerQuit(PlayerQuitEvent event) { + vm.removeCachedPlayerVaultFile(event.getPlayer().getUniqueId()); + } +} diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java index 642cf30..745ee2f 100644 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java @@ -9,12 +9,15 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; +import org.bukkit.scheduler.BukkitRunnable; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; /** * Class to handle vault operations with new UUIDs. @@ -28,6 +31,7 @@ public class UUIDVaultManager { } private final File directory = PlayerVaults.getInstance().getVaultData(); + private final Map cachedVaultFiles = new ConcurrentHashMap<>(); /** * Saves the inventory to the specified player and vault number. @@ -35,10 +39,13 @@ public class UUIDVaultManager { * @param inventory The inventory to be saved. * @param player The player of whose file to save to. * @param number The vault number. - * * @throws java.io.IOException Uh oh! */ public void saveVault(Inventory inventory, UUID player, int number) throws IOException { + saveVault(inventory, player, number, true); + } + + public void saveVault(Inventory inventory, UUID player, int number, boolean async) { int size = inventory.getSize(); YamlConfiguration yaml = getPlayerVaultFile(player); if (size == 54) { @@ -55,7 +62,11 @@ public class UUIDVaultManager { yaml.set("vault" + number + "." + x, ser[x]); } } - saveFile(player, yaml); + if (async) { + saveFile(player, yaml); + } else { + saveFileSync(player, yaml); + } } /** @@ -137,7 +148,6 @@ public class UUIDVaultManager { * @param playerFile the YamlConfiguration file. * @param size the size of the vault. * @param number the vault number. - * * @return inventory if exists, otherwise null. */ private Inventory getInventory(YamlConfiguration playerFile, int size, int number, String title) { @@ -158,7 +168,6 @@ public class UUIDVaultManager { * * @param holder The holder of the vault. * @param number The vault number. - * * @return The inventory of the specified holder and vault number. */ public Inventory getVault(UUID holder, int number) { @@ -189,20 +198,27 @@ public class UUIDVaultManager { * @param sender The sender of whom to send messages to. * @param holder The vault holder. * @param number The vault number. - * * @throws IOException Uh oh! */ - public void deleteVault(CommandSender sender, UUID holder, int number) throws IOException { - File file = new File(directory, holder.toString() + ".yml"); - if (!file.exists()) { - return; - } + public void deleteVault(CommandSender sender, final UUID holder, final int number) throws IOException { + new BukkitRunnable() { + @Override + public void run() { + File file = new File(directory, holder.toString() + ".yml"); + if (!file.exists()) { + return; + } - FileConfiguration playerFile = YamlConfiguration.loadConfiguration(file); - if (file.exists()) { - playerFile.set("vault" + number, null); - playerFile.save(file); - } + FileConfiguration playerFile = YamlConfiguration.loadConfiguration(file); + if (file.exists()) { + playerFile.set("vault" + number, null); + try { + playerFile.save(file); + } catch (IOException ignored) { + } + } + } + }.runTaskAsynchronously(PlayerVaults.getInstance()); OfflinePlayer player = Bukkit.getPlayer(holder); if (player != null && sender.getName().equalsIgnoreCase(player.getName())) { @@ -214,14 +230,31 @@ public class UUIDVaultManager { PlayerVaults.getInstance().getOpenInventories().remove(new VaultViewInfo(holder.toString(), number).toString()); } + // Should only be run asynchronously + public void cachePlayerVaultFile(UUID holder) { + cachedVaultFiles.put(holder, loadPlayerVaultFile(holder)); + } + + public void removeCachedPlayerVaultFile(UUID holder) { + if (cachedVaultFiles.containsKey(holder)) { + cachedVaultFiles.remove(holder); + } + } + /** * Get the holder's vault file. Create if doesn't exist. * * @param holder The vault holder. - * * @return The holder's vault config file. */ public YamlConfiguration getPlayerVaultFile(UUID holder) { + if (cachedVaultFiles.containsKey(holder)) { + return cachedVaultFiles.get(holder); + } + return loadPlayerVaultFile(holder); + } + + public YamlConfiguration loadPlayerVaultFile(UUID holder) { if (!directory.exists()) { directory.mkdir(); } @@ -241,15 +274,43 @@ public class UUIDVaultManager { * * @param holder The vault holder of whose file to save. * @param yaml The config to save. - * * @throws IOException Uh oh! */ - public void saveFile(UUID holder, YamlConfiguration yaml) throws IOException { - File file = new File(directory, holder.toString() + ".yml"); - if (file.exists() && PlayerVaults.getInstance().isBackupsEnabled()) { - file.renameTo(new File(PlayerVaults.getInstance().getBackupsFolder(), holder.toString() + ".yml")); + public void saveFile(final UUID holder, final YamlConfiguration yaml) { + if (Bukkit.getPlayer(holder) != null) { + cachedVaultFiles.put(holder, yaml); + } + final boolean backups = PlayerVaults.getInstance().isBackupsEnabled(); + final File backupsFolder = PlayerVaults.getInstance().getBackupsFolder(); + final File file = new File(directory, holder.toString() + ".yml"); + new BukkitRunnable() { + @Override + public void run() { + if (file.exists() && backups) { + file.renameTo(new File(backupsFolder, holder.toString() + ".yml")); + } + try { + yaml.save(file); + } catch (IOException ignored) { + } + } + }.runTaskAsynchronously(PlayerVaults.getInstance()); + } + + public void saveFileSync(final UUID holder, final YamlConfiguration yaml) { + if (Bukkit.getPlayer(holder) != null) { + cachedVaultFiles.put(holder, yaml); + } + final boolean backups = PlayerVaults.getInstance().isBackupsEnabled(); + final File backupsFolder = PlayerVaults.getInstance().getBackupsFolder(); + final File file = new File(directory, holder.toString() + ".yml"); + if (file.exists() && backups) { + file.renameTo(new File(backupsFolder, holder.toString() + ".yml")); + } + try { + yaml.save(file); + } catch (IOException ignored) { } - yaml.save(file); } /**