summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsnowleo <schneeleo@gmail.com>2012-10-07 22:18:30 +0200
committersnowleo <schneeleo@gmail.com>2012-10-07 22:18:53 +0200
commit524531a0902a5d368decce6ce6bd714c7d429062 (patch)
tree230cdec7946d167e64a0e3054fc88671cdc51917
parent7a36150f3ca52c1900ca16940decd5317ad5e607 (diff)
downloadEssentials-524531a0902a5d368decce6ce6bd714c7d429062.tar
Essentials-524531a0902a5d368decce6ce6bd714c7d429062.tar.gz
Essentials-524531a0902a5d368decce6ce6bd714c7d429062.tar.lz
Essentials-524531a0902a5d368decce6ce6bd714c7d429062.tar.xz
Essentials-524531a0902a5d368decce6ce6bd714c7d429062.zip
Queued writing of the files to reduce disk io
-rw-r--r--Essentials/src/net/ess3/Essentials.java138
-rw-r--r--Essentials/src/net/ess3/Jails.java8
-rw-r--r--Essentials/src/net/ess3/Kits.java8
-rw-r--r--Essentials/src/net/ess3/api/IEssentials.java5
-rw-r--r--Essentials/src/net/ess3/commands/Commandessentials.java2
-rw-r--r--Essentials/src/net/ess3/economy/MoneyHolder.java9
-rw-r--r--Essentials/src/net/ess3/economy/WorthHolder.java8
-rw-r--r--Essentials/src/net/ess3/ranks/RanksStorage.java8
-rw-r--r--Essentials/src/net/ess3/settings/SettingsHolder.java8
-rw-r--r--Essentials/src/net/ess3/settings/SpawnsHolder.java8
-rw-r--r--Essentials/src/net/ess3/settings/WarpHolder.java24
-rw-r--r--Essentials/src/net/ess3/storage/AbstractDelayedYamlFileReader.java25
-rw-r--r--Essentials/src/net/ess3/storage/AbstractDelayedYamlFileWriter.java16
-rw-r--r--Essentials/src/net/ess3/storage/AsyncStorageObjectHolder.java57
-rw-r--r--Essentials/src/net/ess3/storage/StorageQueue.java141
-rw-r--r--Essentials/src/net/ess3/user/User.java2
-rw-r--r--Essentials/src/net/ess3/user/UserBase.java17
-rw-r--r--Essentials/src/net/ess3/user/UserMap.java7
-rw-r--r--EssentialsAntiBuild/src/net/ess3/antibuild/AntiBuildHolder.java9
-rw-r--r--EssentialsGeoIP/src/net/ess3/geoip/ConfigHolder.java9
-rw-r--r--EssentialsProtect/src/net/ess3/protect/ProtectHolder.java9
-rw-r--r--EssentialsSigns/src/net/ess3/signs/SignsConfigHolder.java9
22 files changed, 245 insertions, 282 deletions
diff --git a/Essentials/src/net/ess3/Essentials.java b/Essentials/src/net/ess3/Essentials.java
index ef503f18a..c0203f9dc 100644
--- a/Essentials/src/net/ess3/Essentials.java
+++ b/Essentials/src/net/ess3/Essentials.java
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import lombok.Getter;
+import lombok.Setter;
import static net.ess3.I18n._;
import net.ess3.api.*;
import net.ess3.backup.Backup;
@@ -36,6 +37,7 @@ import net.ess3.metrics.Metrics;
import net.ess3.ranks.RanksStorage;
import net.ess3.settings.SettingsHolder;
import net.ess3.settings.SpawnsHolder;
+import net.ess3.storage.StorageQueue;
import net.ess3.user.UserMap;
import net.ess3.utils.ExecuteTimer;
import org.bukkit.Server;
@@ -46,22 +48,34 @@ import org.bukkit.plugin.InvalidDescriptionException;
public class Essentials implements IEssentials
{
+ @Getter
private transient ISettings settings;
+ @Getter
private transient IJails jails;
+ @Getter
private transient IKits kits;
+ @Getter
private transient IWarps warps;
+ @Getter
private transient IWorth worth;
- private transient List<IReload> reloadList;
+ @Getter
private transient IBackup backup;
+ @Getter
private transient IItemDb itemDb;
- private transient IRanks groups;
+ @Getter
+ @Setter
+ private transient IRanks ranks;
+ @Getter
private transient SpawnsHolder spawns;
+ @Getter
private transient final Methods paymentMethod = new Methods();
+ @Getter
private transient IUserMap userMap;
- private transient ExecuteTimer execTimer;
@Getter
private final I18n i18n;
+ @Getter
private transient ICommandHandler commandHandler;
+ @Getter
private transient Economy economy;
@Getter
private final Server server;
@@ -69,28 +83,29 @@ public class Essentials implements IEssentials
private final Logger logger;
@Getter
private final IPlugin plugin;
- public static boolean testing;
+ @Getter
+ @Setter
private transient Metrics metrics;
@Getter
private transient EssentialsTimer timer;
@Getter
private transient List<String> vanishedPlayers = new ArrayList<String>();
+ @Getter
+ private final transient StorageQueue storageQueue;
+ private transient ExecuteTimer execTimer;
+ public static boolean testing;
+ private transient List<IReload> reloadList;
public Essentials(final Server server, final Logger logger, final IPlugin plugin)
{
this.server = server;
this.logger = logger;
this.plugin = plugin;
+ this.storageQueue = new StorageQueue(plugin);
this.i18n = new I18n(this);
i18n.onEnable();
}
- @Override
- public ISettings getSettings()
- {
- return settings;
- }
-
public void setupForTesting(final Server server) throws IOException, InvalidDescriptionException
{
testing = true;
@@ -106,6 +121,7 @@ public class Essentials implements IEssentials
logger.log(Level.INFO, I18n._("usingTempFolderForTesting"));
logger.log(Level.INFO, dataFolder.toString());
+ storageQueue.setEnabled(true);
settings = new SettingsHolder(this);
i18n.updateLocale("en");
userMap = new UserMap(this);
@@ -115,6 +131,7 @@ public class Essentials implements IEssentials
@Override
public void onEnable()
{
+ storageQueue.setEnabled(true);
execTimer = new ExecuteTimer();
execTimer.start();
@@ -130,8 +147,8 @@ public class Essentials implements IEssentials
userMap = new UserMap(this);
reloadList.add(userMap);
execTimer.mark("Init(Usermap)");
- groups = new RanksStorage(this);
- reloadList.add((RanksStorage)groups);
+ ranks = new RanksStorage(this);
+ reloadList.add((RanksStorage)ranks);
warps = new Warps(this);
reloadList.add(warps);
execTimer.mark("Init(Spawn/Warp)");
@@ -181,6 +198,7 @@ public class Essentials implements IEssentials
}
i18n.onDisable();
Trade.closeLog();
+ storageQueue.setEnabled(false);
}
@Override
@@ -198,48 +216,6 @@ public class Essentials implements IEssentials
}
@Override
- public IJails getJails()
- {
- return jails;
- }
-
- @Override
- public IKits getKits()
- {
- return kits;
- }
-
- @Override
- public IWarps getWarps()
- {
- return warps;
- }
-
- @Override
- public IWorth getWorth()
- {
- return worth;
- }
-
- @Override
- public IBackup getBackup()
- {
- return backup;
- }
-
- @Override
- public Metrics getMetrics()
- {
- return metrics;
- }
-
- @Override
- public void setMetrics(Metrics metrics)
- {
- this.metrics = metrics;
- }
-
- @Override
public World getWorld(final String name)
{
if (name.matches("[0-9]+"))
@@ -260,12 +236,6 @@ public class Essentials implements IEssentials
}
@Override
- public Methods getPaymentMethod()
- {
- return paymentMethod;
- }
-
- @Override
public int broadcastMessage(final IUser sender, final String message)
{
if (sender == null)
@@ -289,56 +259,8 @@ public class Essentials implements IEssentials
}
@Override
- public IItemDb getItemDb()
- {
- return itemDb;
- }
-
- @Override
- public IUserMap getUserMap()
- {
- return userMap;
- }
-
- @Override
- public IRanks getRanks()
- {
- return groups;
- }
-
- @Override
- public ICommandHandler getCommandHandler()
- {
- return commandHandler;
- }
-
- @Override
- public void setRanks(final IRanks groups)
- {
- this.groups = groups;
- }
-
- @Override
public void removeReloadListener(IReload groups)
{
this.reloadList.remove(groups);
}
-
- @Override
- public IEconomy getEconomy()
- {
- return economy;
- }
-
- @Override
- public SpawnsHolder getSpawns()
- {
- return spawns;
- }
-
- @Override
- public void reload()
- {
- //do something
- }
}
diff --git a/Essentials/src/net/ess3/Jails.java b/Essentials/src/net/ess3/Jails.java
index 93daa0cdb..1ac51142b 100644
--- a/Essentials/src/net/ess3/Jails.java
+++ b/Essentials/src/net/ess3/Jails.java
@@ -31,7 +31,7 @@ public class Jails extends AsyncStorageObjectHolder<net.ess3.settings.Jails> imp
public Jails(final IEssentials ess)
{
- super(ess, net.ess3.settings.Jails.class);
+ super(ess, net.ess3.settings.Jails.class, new File(ess.getPlugin().getDataFolder(), "jail.yml"));
onReload();
registerListeners();
}
@@ -46,12 +46,6 @@ public class Jails extends AsyncStorageObjectHolder<net.ess3.settings.Jails> imp
}
@Override
- public File getStorageFile()
- {
- return new File(ess.getPlugin().getDataFolder(), "jail.yml");
- }
-
- @Override
public Location getJail(final String jailName) throws Exception
{
if (getData().getJails() == null || jailName == null
diff --git a/Essentials/src/net/ess3/Kits.java b/Essentials/src/net/ess3/Kits.java
index 4e8e15226..e464caf4e 100644
--- a/Essentials/src/net/ess3/Kits.java
+++ b/Essentials/src/net/ess3/Kits.java
@@ -19,17 +19,11 @@ public class Kits extends AsyncStorageObjectHolder<net.ess3.settings.Kits> imple
{
public Kits(final IEssentials ess)
{
- super(ess, net.ess3.settings.Kits.class);
+ super(ess, net.ess3.settings.Kits.class, new File(ess.getPlugin().getDataFolder(), "kits.yml"));
onReload();
}
@Override
- public File getStorageFile() throws IOException
- {
- return new File(ess.getPlugin().getDataFolder(), "kits.yml");
- }
-
- @Override
public Kit getKit(String kitName) throws Exception
{
if (getData().getKits() == null || kitName == null
diff --git a/Essentials/src/net/ess3/api/IEssentials.java b/Essentials/src/net/ess3/api/IEssentials.java
index 0833b3d2b..ea821d4dc 100644
--- a/Essentials/src/net/ess3/api/IEssentials.java
+++ b/Essentials/src/net/ess3/api/IEssentials.java
@@ -6,6 +6,7 @@ import net.ess3.EssentialsTimer;
import net.ess3.economy.register.Methods;
import net.ess3.metrics.Metrics;
import net.ess3.settings.SpawnsHolder;
+import net.ess3.storage.StorageQueue;
import org.bukkit.Server;
import org.bukkit.World;
@@ -42,8 +43,6 @@ public interface IEssentials extends IComponent
Methods getPaymentMethod();
- void reload();
-
void setRanks(IRanks groups);
void removeReloadListener(IReload groups);
@@ -65,4 +64,6 @@ public interface IEssentials extends IComponent
void setMetrics(Metrics metrics);
SpawnsHolder getSpawns();
+
+ StorageQueue getStorageQueue();
}
diff --git a/Essentials/src/net/ess3/commands/Commandessentials.java b/Essentials/src/net/ess3/commands/Commandessentials.java
index 0d2311c45..3c9492c50 100644
--- a/Essentials/src/net/ess3/commands/Commandessentials.java
+++ b/Essentials/src/net/ess3/commands/Commandessentials.java
@@ -51,7 +51,7 @@ public class Commandessentials extends EssentialsCommand
private void run_reload(final CommandSender sender, final String[] args) throws Exception
{
- ess.reload();
+ ess.onReload();
sender.sendMessage(_("essentialsReload", ess.getPlugin().getVersion()));
}
}
diff --git a/Essentials/src/net/ess3/economy/MoneyHolder.java b/Essentials/src/net/ess3/economy/MoneyHolder.java
index 386dae7af..cc0d4c79a 100644
--- a/Essentials/src/net/ess3/economy/MoneyHolder.java
+++ b/Essentials/src/net/ess3/economy/MoneyHolder.java
@@ -1,7 +1,6 @@
package net.ess3.economy;
import java.io.File;
-import java.io.IOException;
import net.ess3.api.IEssentials;
import net.ess3.storage.AsyncStorageObjectHolder;
@@ -24,13 +23,7 @@ public class MoneyHolder extends AsyncStorageObjectHolder<Money>
public MoneyHolder(IEssentials ess)
{
- super(ess, Money.class);
+ super(ess, Money.class, new File(ess.getPlugin().getDataFolder(), "economy_npcs.yml"));
onReload();
}
-
- @Override
- public File getStorageFile() throws IOException
- {
- return new File(ess.getPlugin().getDataFolder(), "economy_npcs.yml");
- }
}
diff --git a/Essentials/src/net/ess3/economy/WorthHolder.java b/Essentials/src/net/ess3/economy/WorthHolder.java
index fec53cd43..26ce23e31 100644
--- a/Essentials/src/net/ess3/economy/WorthHolder.java
+++ b/Essentials/src/net/ess3/economy/WorthHolder.java
@@ -26,7 +26,7 @@ public class WorthHolder extends AsyncStorageObjectHolder<net.ess3.economy.Worth
public WorthHolder(final IEssentials ess)
{
- super(ess, net.ess3.economy.Worth.class);
+ super(ess, net.ess3.economy.Worth.class, new File(ess.getPlugin().getDataFolder(), "worth.yml"));
onReload(false);
}
@@ -72,10 +72,4 @@ public class WorthHolder extends AsyncStorageObjectHolder<net.ess3.economy.Worth
getData().setSellPrice(itemStack.getData(), price);
queueSave();
}
-
- @Override
- public File getStorageFile() throws IOException
- {
- return new File(ess.getPlugin().getDataFolder(), "worth.yml");
- }
}
diff --git a/Essentials/src/net/ess3/ranks/RanksStorage.java b/Essentials/src/net/ess3/ranks/RanksStorage.java
index b0a8bc1e2..325d35b18 100644
--- a/Essentials/src/net/ess3/ranks/RanksStorage.java
+++ b/Essentials/src/net/ess3/ranks/RanksStorage.java
@@ -30,16 +30,10 @@ public class RanksStorage extends AsyncStorageObjectHolder<Ranks> implements IRa
public RanksStorage(final IEssentials ess)
{
- super(ess, Ranks.class);
+ super(ess, Ranks.class, new File(ess.getPlugin().getDataFolder(), "ranks.yml"));
onReload();
}
- @Override
- public File getStorageFile()
- {
- return new File(ess.getPlugin().getDataFolder(), "ranks.yml");
- }
-
public Collection<Entry<String, RankOptions>> getGroups(final IUser player)
{
final Map<String, RankOptions> groups = getData().getRanks();
diff --git a/Essentials/src/net/ess3/settings/SettingsHolder.java b/Essentials/src/net/ess3/settings/SettingsHolder.java
index b20b7ab22..c0e7d6dd4 100644
--- a/Essentials/src/net/ess3/settings/SettingsHolder.java
+++ b/Essentials/src/net/ess3/settings/SettingsHolder.java
@@ -21,7 +21,7 @@ public class SettingsHolder extends AsyncStorageObjectHolder<Settings> implement
public SettingsHolder(final IEssentials ess)
{
- super(ess, Settings.class);
+ super(ess, Settings.class, new File(ess.getPlugin().getDataFolder(), "settings.yml"));
onReload();
}
@@ -34,12 +34,6 @@ public class SettingsHolder extends AsyncStorageObjectHolder<Settings> implement
}
@Override
- public File getStorageFile()
- {
- return new File(ess.getPlugin().getDataFolder(), "settings.yml");
- }
-
- @Override
public String getLocale()
{
return getData().getGeneral().getLocale();
diff --git a/Essentials/src/net/ess3/settings/SpawnsHolder.java b/Essentials/src/net/ess3/settings/SpawnsHolder.java
index a1c7e88d3..9460b0b62 100644
--- a/Essentials/src/net/ess3/settings/SpawnsHolder.java
+++ b/Essentials/src/net/ess3/settings/SpawnsHolder.java
@@ -40,17 +40,11 @@ public class SpawnsHolder extends AsyncStorageObjectHolder<Spawns> implements IE
public SpawnsHolder(final IEssentials ess)
{
- super(ess, Spawns.class);
+ super(ess, Spawns.class, new File(ess.getPlugin().getDataFolder(), "spawn.yml"));
onReload();
registerListeners();
}
- @Override
- public File getStorageFile()
- {
- return new File(ess.getPlugin().getDataFolder(), "spawn.yml");
- }
-
public void setSpawn(final Location loc, final String group)
{
getData().addSpawn(group, loc);
diff --git a/Essentials/src/net/ess3/settings/WarpHolder.java b/Essentials/src/net/ess3/settings/WarpHolder.java
index 06bf47121..6da9d8528 100644
--- a/Essentials/src/net/ess3/settings/WarpHolder.java
+++ b/Essentials/src/net/ess3/settings/WarpHolder.java
@@ -1,7 +1,5 @@
package net.ess3.settings;
-import java.io.File;
-import java.io.IOException;
import net.ess3.api.IEssentials;
import net.ess3.api.IWarp;
import net.ess3.api.InvalidNameException;
@@ -10,39 +8,21 @@ import net.ess3.storage.AsyncStorageObjectHolder;
public class WarpHolder extends AsyncStorageObjectHolder<Warp> implements IWarp
{
-
@Override
public void finishRead()
{
-
}
@Override
public void finishWrite()
{
-
}
-
private final String name;
- public WarpHolder(String name, IEssentials ess)
+ public WarpHolder(String name, IEssentials ess) throws InvalidNameException
{
- super(ess, Warp.class);
+ super(ess, Warp.class, ess.getWarps().getWarpFile(name));
this.name = name;
onReload();
}
-
- @Override
- public File getStorageFile() throws IOException
- {
- try
- {
- return ess.getWarps().getWarpFile(name);
- }
- catch (InvalidNameException ex)
- {
- throw new IOException(ex.getMessage(), ex);
- }
- }
-
}
diff --git a/Essentials/src/net/ess3/storage/AbstractDelayedYamlFileReader.java b/Essentials/src/net/ess3/storage/AbstractDelayedYamlFileReader.java
index bb39742c8..b38f5750b 100644
--- a/Essentials/src/net/ess3/storage/AbstractDelayedYamlFileReader.java
+++ b/Essentials/src/net/ess3/storage/AbstractDelayedYamlFileReader.java
@@ -4,7 +4,6 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
-import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import net.ess3.api.IEssentials;
import org.bukkit.Bukkit;
@@ -12,10 +11,8 @@ import org.bukkit.Bukkit;
public abstract class AbstractDelayedYamlFileReader<T extends StorageObject> implements Runnable
{
-
private final transient Class<T> clazz;
private final transient IEssentials ess;
- private final transient ReentrantLock lock = new ReentrantLock();
public AbstractDelayedYamlFileReader(final IEssentials ess, final Class<T> clazz)
{
@@ -35,16 +32,14 @@ public abstract class AbstractDelayedYamlFileReader<T extends StorageObject> imp
}
}
- public abstract File onStart() throws IOException;
+ public abstract File onStart();
@Override
public void run()
{
- File file = null;
- lock.lock();
- try
+ final File file = onStart();
+ synchronized (file)
{
- file = onStart();
try
{
final FileReader reader = new FileReader(file);
@@ -69,7 +64,7 @@ public abstract class AbstractDelayedYamlFileReader<T extends StorageObject> imp
catch (FileNotFoundException ex)
{
onException(ex);
- Bukkit.getLogger().log(Level.INFO, "File not found: {0}", file.toString());
+ Bukkit.getLogger().log(Level.INFO, "File not found: " + file.toString());
}
catch (ObjectLoadException ex)
{
@@ -79,18 +74,6 @@ public abstract class AbstractDelayedYamlFileReader<T extends StorageObject> imp
Bukkit.getLogger().log(Level.SEVERE, "The file " + file.toString() + " is broken, it has been renamed to " + broken.toString(), ex.getCause());
}
}
- catch (IOException ex)
- {
- onException(ex);
- if (ess.getSettings() == null || ess.getSettings().isDebug())
- {
- Bukkit.getLogger().log(Level.INFO, "File not found: " + file.toString());
- }
- }
- finally
- {
- lock.unlock();
- }
}
public abstract void onSuccess(T object);
diff --git a/Essentials/src/net/ess3/storage/AbstractDelayedYamlFileWriter.java b/Essentials/src/net/ess3/storage/AbstractDelayedYamlFileWriter.java
index 0be1feac3..29b563489 100644
--- a/Essentials/src/net/ess3/storage/AbstractDelayedYamlFileWriter.java
+++ b/Essentials/src/net/ess3/storage/AbstractDelayedYamlFileWriter.java
@@ -2,7 +2,6 @@ package net.ess3.storage;
import java.io.File;
import java.io.FileNotFoundException;
-import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
@@ -25,17 +24,16 @@ public abstract class AbstractDelayedYamlFileWriter implements Runnable
ess.getPlugin().scheduleAsyncDelayedTask(this);
}
- public abstract File getFile() throws IOException;
+ public abstract File getFile();
public abstract StorageObject getObject();
@Override
public void run()
{
- lock.lock();
- try
+ final File file = getFile();
+ synchronized (file)
{
- final File file = getFile();
PrintWriter pw = null;
try
{
@@ -61,14 +59,6 @@ public abstract class AbstractDelayedYamlFileWriter implements Runnable
}
}
}
- catch (IOException ex)
- {
- Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
- }
- finally
- {
- lock.unlock();
- }
}
public abstract void onFinish();
diff --git a/Essentials/src/net/ess3/storage/AsyncStorageObjectHolder.java b/Essentials/src/net/ess3/storage/AsyncStorageObjectHolder.java
index 3c3395c73..5c55169d1 100644
--- a/Essentials/src/net/ess3/storage/AsyncStorageObjectHolder.java
+++ b/Essentials/src/net/ess3/storage/AsyncStorageObjectHolder.java
@@ -4,6 +4,8 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import net.ess3.api.IEssentials;
import org.bukkit.Bukkit;
@@ -17,11 +19,14 @@ public abstract class AsyncStorageObjectHolder<T extends StorageObject> implemen
private final transient StorageObjectDataWriter writer;
private final transient StorageObjectDataReader reader;
private final transient AtomicBoolean loaded = new AtomicBoolean(false);
+ private volatile long savetime = 0;
+ private final transient File file;
- public AsyncStorageObjectHolder(final IEssentials ess, final Class<T> clazz)
+ public AsyncStorageObjectHolder(final IEssentials ess, final Class<T> clazz, final File file)
{
this.ess = ess;
this.clazz = clazz;
+ this.file = file;
writer = new StorageObjectDataWriter();
reader = new StorageObjectDataReader();
try
@@ -53,9 +58,9 @@ public abstract class AsyncStorageObjectHolder<T extends StorageObject> implemen
@Override
public void queueSave()
{
- writer.schedule();
+ ess.getStorageQueue().queue(this);
}
-
+
@Override
public void onReload()
{
@@ -66,13 +71,42 @@ public abstract class AsyncStorageObjectHolder<T extends StorageObject> implemen
{
reader.schedule(instant);
}
-
+
+ @Override
+ public String toString()
+ {
+ return file.getAbsolutePath();
+ }
+
public abstract void finishRead();
-
+
public abstract void finishWrite();
-
- public abstract File getStorageFile() throws IOException;
+ public StorageQueue.RequestState getRequestState(long timestamp)
+ {
+ if (savetime == 0 || savetime < timestamp || (timestamp < 0 && savetime > 0))
+ {
+ final long now = System.nanoTime();
+ if (Math.abs(now - savetime) < StorageQueue.DELAY)
+ {
+ return StorageQueue.RequestState.REQUEUE;
+ }
+ else
+ {
+ savetime = System.nanoTime();
+ return StorageQueue.RequestState.SCHEDULE;
+ }
+ }
+ else
+ {
+ return StorageQueue.RequestState.FINISHED;
+ }
+ }
+
+ Runnable getFileWriter()
+ {
+ return writer;
+ }
private class StorageObjectDataWriter extends AbstractDelayedYamlFileWriter
{
@@ -82,9 +116,9 @@ public abstract class AsyncStorageObjectHolder<T extends StorageObject> implemen
}
@Override
- public File getFile() throws IOException
+ public File getFile()
{
- return getStorageFile();
+ return file;
}
@Override
@@ -109,9 +143,9 @@ public abstract class AsyncStorageObjectHolder<T extends StorageObject> implemen
}
@Override
- public File onStart() throws IOException
+ public File onStart()
{
- return getStorageFile();
+ return file;
}
@Override
@@ -122,6 +156,7 @@ public abstract class AsyncStorageObjectHolder<T extends StorageObject> implemen
data = object;
}
loaded.set(true);
+ finishRead();
}
@Override
diff --git a/Essentials/src/net/ess3/storage/StorageQueue.java b/Essentials/src/net/ess3/storage/StorageQueue.java
new file mode 100644
index 000000000..304de4ae6
--- /dev/null
+++ b/Essentials/src/net/ess3/storage/StorageQueue.java
@@ -0,0 +1,141 @@
+package net.ess3.storage;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import net.ess3.api.IPlugin;
+
+
+public class StorageQueue implements Runnable
+{
+ private DelayQueue<WriteRequest> queue = new DelayQueue<WriteRequest>();
+ public final static long DELAY = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS);
+ private final AtomicBoolean enabled = new AtomicBoolean(false);
+ private final transient Object lock = new Object();
+ private final IPlugin plugin;
+
+ public StorageQueue(IPlugin plugin)
+ {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public void run()
+ {
+ synchronized (lock)
+ {
+ List<WriteRequest> requests = new ArrayList<WriteRequest>();
+ while (enabled.get() || !queue.isEmpty())
+ {
+ try
+ {
+ queue.drainTo(requests);
+ for (WriteRequest request : requests)
+ {
+ RequestState state = request.getRequestState();
+ if (state == RequestState.REQUEUE)
+ {
+ queue.add(request);
+ continue;
+ }
+ if (state == RequestState.SCHEDULE)
+ {
+ plugin.scheduleAsyncDelayedTask(request.getRunnable());
+ }
+ }
+ requests.clear();
+ Thread.sleep(100);
+ }
+ catch (InterruptedException ex)
+ {
+ continue;
+ }
+ }
+ }
+ }
+
+ public void queue(AsyncStorageObjectHolder objectHolder)
+ {
+ if (!enabled.get())
+ {
+ plugin.getLogger().log(Level.SEVERE,
+ "File " + objectHolder.toString() + " is queued for saving, while the queue is disabled. It's possible that it will not be saved!",
+ new RuntimeException());
+ }
+ queue.add(new WriteRequest(objectHolder));
+ }
+
+ private void startThread()
+ {
+ synchronized (lock)
+ {
+ plugin.scheduleAsyncDelayedTask(this);
+ }
+ }
+
+ public void setEnabled(boolean enabled)
+ {
+ if (this.enabled.getAndSet(enabled) != enabled && enabled)
+ {
+ startThread();
+ }
+ }
+
+
+ private class WriteRequest implements Delayed
+ {
+ private final AsyncStorageObjectHolder objectHolder;
+ private final long timestamp;
+
+ public WriteRequest(AsyncStorageObjectHolder objectHolder)
+ {
+ this.objectHolder = objectHolder;
+ this.timestamp = System.nanoTime();
+ }
+
+ @Override
+ public long getDelay(final TimeUnit tu)
+ {
+ if (tu == TimeUnit.NANOSECONDS)
+ {
+ final long now = System.nanoTime();
+ return DELAY - Math.abs(now - timestamp);
+ }
+ else
+ {
+ return tu.convert(getDelay(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS);
+ }
+ }
+
+ @Override
+ public int compareTo(final Delayed t)
+ {
+ final long a = getDelay(TimeUnit.NANOSECONDS);
+ final long b = t.getDelay(TimeUnit.NANOSECONDS);
+ return a < b ? -1 : a == b ? 0 : 1;
+ }
+
+ public RequestState getRequestState()
+ {
+ return objectHolder.getRequestState(timestamp);
+ }
+
+ public Runnable getRunnable()
+ {
+ return objectHolder.getFileWriter();
+ }
+ }
+
+
+ public enum RequestState
+ {
+ REQUEUE,
+ SCHEDULE,
+ FINISHED
+ }
+}
diff --git a/Essentials/src/net/ess3/user/User.java b/Essentials/src/net/ess3/user/User.java
index 61090780e..9c0ed3bad 100644
--- a/Essentials/src/net/ess3/user/User.java
+++ b/Essentials/src/net/ess3/user/User.java
@@ -54,7 +54,7 @@ public class User extends UserBase implements IUser
private AtomicBoolean gotMailInfo = new AtomicBoolean(false);
private WeakReference<Player> playerCache;
- public User(final OfflinePlayer base, final IEssentials ess)
+ public User(final OfflinePlayer base, final IEssentials ess) throws InvalidNameException
{
super(base, ess);
teleport = new Teleport(this, ess);
diff --git a/Essentials/src/net/ess3/user/UserBase.java b/Essentials/src/net/ess3/user/UserBase.java
index bb46ab10d..abcaf8371 100644
--- a/Essentials/src/net/ess3/user/UserBase.java
+++ b/Essentials/src/net/ess3/user/UserBase.java
@@ -29,9 +29,9 @@ public abstract class UserBase extends AsyncStorageObjectHolder<UserData> implem
@Delegate
protected final OfflinePlayer offlinePlayer;
- public UserBase(final OfflinePlayer base, final IEssentials ess)
+ public UserBase(final OfflinePlayer base, final IEssentials ess) throws InvalidNameException
{
- super(ess, UserData.class);
+ super(ess, UserData.class, ess.getUserMap().getUserFile(base.getName()));
this.offlinePlayer = base;
onReload();
}
@@ -160,19 +160,6 @@ public abstract class UserBase extends AsyncStorageObjectHolder<UserData> implem
throw new UnsupportedOperationException("Not supported yet.");
}
- @Override
- public File getStorageFile() throws IOException
- {
- try
- {
- return ess.getUserMap().getUserFile(getName());
- }
- catch (InvalidNameException ex)
- {
- throw new IOException(ex.getMessage(), ex);
- }
- }
-
public long getTimestamp(final UserData.TimestampType name)
{
return getData().getTimestamp(name);
diff --git a/Essentials/src/net/ess3/user/UserMap.java b/Essentials/src/net/ess3/user/UserMap.java
index 43ca9b2f8..8ba5250ff 100644
--- a/Essentials/src/net/ess3/user/UserMap.java
+++ b/Essentials/src/net/ess3/user/UserMap.java
@@ -90,12 +90,7 @@ public class UserMap extends StorageObjectMap<IUser> implements IUserMap
@Override
public IUser getUser(final Player player)
{
- IUser user = getObject(player.getName());
- if (user == null)
- {
- user = new User(player, ess);
- }
- return user;
+ return getObject(player.getName());
}
@Override
diff --git a/EssentialsAntiBuild/src/net/ess3/antibuild/AntiBuildHolder.java b/EssentialsAntiBuild/src/net/ess3/antibuild/AntiBuildHolder.java
index ef3aebc06..981fb0577 100644
--- a/EssentialsAntiBuild/src/net/ess3/antibuild/AntiBuildHolder.java
+++ b/EssentialsAntiBuild/src/net/ess3/antibuild/AntiBuildHolder.java
@@ -1,7 +1,6 @@
package net.ess3.antibuild;
import java.io.File;
-import java.io.IOException;
import net.ess3.api.IEssentials;
import net.ess3.settings.antibuild.AntiBuild;
import net.ess3.storage.AsyncStorageObjectHolder;
@@ -10,13 +9,7 @@ public class AntiBuildHolder extends AsyncStorageObjectHolder<AntiBuild>
{
public AntiBuildHolder(final IEssentials ess)
{
- super(ess, AntiBuild.class);
- }
-
- @Override
- public File getStorageFile() throws IOException
- {
- return new File(ess.getPlugin().getDataFolder(), "protect.yml");
+ super(ess, AntiBuild.class, new File(ess.getPlugin().getDataFolder(), "protect.yml"));
}
@Override
diff --git a/EssentialsGeoIP/src/net/ess3/geoip/ConfigHolder.java b/EssentialsGeoIP/src/net/ess3/geoip/ConfigHolder.java
index 4f6faba69..0edb7bc50 100644
--- a/EssentialsGeoIP/src/net/ess3/geoip/ConfigHolder.java
+++ b/EssentialsGeoIP/src/net/ess3/geoip/ConfigHolder.java
@@ -1,7 +1,6 @@
package net.ess3.geoip;
import java.io.File;
-import java.io.IOException;
import net.ess3.api.IEssentials;
import net.ess3.settings.geoip.GeoIP;
import net.ess3.storage.AsyncStorageObjectHolder;
@@ -14,18 +13,12 @@ public class ConfigHolder extends AsyncStorageObjectHolder<GeoIP>
public ConfigHolder(final IEssentials ess, final Plugin geoip)
{
- super(ess, GeoIP.class);
+ super(ess, GeoIP.class, new File(geoip.getDataFolder(), "config.yml"));
this.geoip = geoip;
onReload(true);
}
@Override
- public File getStorageFile() throws IOException
- {
- return new File(geoip.getDataFolder(), "config.yml");
- }
-
- @Override
public void finishRead()
{
}
diff --git a/EssentialsProtect/src/net/ess3/protect/ProtectHolder.java b/EssentialsProtect/src/net/ess3/protect/ProtectHolder.java
index 507bbf596..9718fbe79 100644
--- a/EssentialsProtect/src/net/ess3/protect/ProtectHolder.java
+++ b/EssentialsProtect/src/net/ess3/protect/ProtectHolder.java
@@ -1,7 +1,6 @@
package net.ess3.protect;
import java.io.File;
-import java.io.IOException;
import net.ess3.api.IEssentials;
import net.ess3.settings.protect.Protect;
import net.ess3.storage.AsyncStorageObjectHolder;
@@ -11,13 +10,7 @@ public class ProtectHolder extends AsyncStorageObjectHolder<Protect>
{
public ProtectHolder(final IEssentials ess)
{
- super(ess, Protect.class);
- }
-
- @Override
- public File getStorageFile() throws IOException
- {
- return new File(ess.getPlugin().getDataFolder(), "protect.yml");
+ super(ess, Protect.class, new File(ess.getPlugin().getDataFolder(), "protect.yml"));
}
@Override
diff --git a/EssentialsSigns/src/net/ess3/signs/SignsConfigHolder.java b/EssentialsSigns/src/net/ess3/signs/SignsConfigHolder.java
index 0f74a965d..5f3a767f7 100644
--- a/EssentialsSigns/src/net/ess3/signs/SignsConfigHolder.java
+++ b/EssentialsSigns/src/net/ess3/signs/SignsConfigHolder.java
@@ -1,7 +1,6 @@
package net.ess3.signs;
import java.io.File;
-import java.io.IOException;
import java.util.*;
import net.ess3.api.IEssentials;
import net.ess3.storage.AsyncStorageObjectHolder;
@@ -16,7 +15,7 @@ public class SignsConfigHolder extends AsyncStorageObjectHolder<SignsConfig>
public SignsConfigHolder(final IEssentials ess, final Plugin plugin)
{
- super(ess, SignsConfig.class);
+ super(ess, SignsConfig.class, new File(plugin.getDataFolder(), "config.yml"));
this.plugin = plugin;
onReload();
final Map<String, Boolean> signs = getData().getSigns();
@@ -44,12 +43,6 @@ public class SignsConfigHolder extends AsyncStorageObjectHolder<SignsConfig>
queueSave();
}
- @Override
- public File getStorageFile() throws IOException
- {
- return new File(plugin.getDataFolder(), "config.yml");
- }
-
public Set<EssentialsSign> getEnabledSigns()
{
return enabledSigns;