summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsnowleo <schneeleo@gmail.com>2013-04-22 23:31:11 +0200
committersnowleo <schneeleo@gmail.com>2013-04-22 23:31:11 +0200
commit9b821545fde9b5a4e3e1f3ef3d83b32bf2a5e09a (patch)
treea5f1336cf2458e72477755811dbcb4a6a6bd0f04
parent27853b78f890609446c30581db0aaa0c61014a60 (diff)
downloadEssentials-9b821545fde9b5a4e3e1f3ef3d83b32bf2a5e09a.tar
Essentials-9b821545fde9b5a4e3e1f3ef3d83b32bf2a5e09a.tar.gz
Essentials-9b821545fde9b5a4e3e1f3ef3d83b32bf2a5e09a.tar.lz
Essentials-9b821545fde9b5a4e3e1f3ef3d83b32bf2a5e09a.tar.xz
Essentials-9b821545fde9b5a4e3e1f3ef3d83b32bf2a5e09a.zip
Delayed write to file (experimental)
-rw-r--r--Essentials/src/com/earth2me/essentials/EssentialsConf.java113
1 files changed, 87 insertions, 26 deletions
diff --git a/Essentials/src/com/earth2me/essentials/EssentialsConf.java b/Essentials/src/com/earth2me/essentials/EssentialsConf.java
index 175afb110..8f0c69dd6 100644
--- a/Essentials/src/com/earth2me/essentials/EssentialsConf.java
+++ b/Essentials/src/com/earth2me/essentials/EssentialsConf.java
@@ -9,6 +9,9 @@ import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;
import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.*;
@@ -24,21 +27,27 @@ import org.bukkit.util.Vector;
public class EssentialsConf extends YamlConfiguration
{
private static final Logger LOGGER = Logger.getLogger("Minecraft");
- private transient File configFile;
- private transient String templateName = null;
- private transient Class<?> resourceClass = EssentialsConf.class;
+ private final File configFile;
+ private String templateName = null;
+ private Class<?> resourceClass = EssentialsConf.class;
private static final Charset UTF8 = Charset.forName("UTF-8");
+ private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
+ private final AtomicInteger pendingDiskWrites = new AtomicInteger(0);
public EssentialsConf(final File configFile)
{
super();
- this.configFile = configFile;
+ this.configFile = configFile.getAbsoluteFile();
}
private final byte[] bytebuffer = new byte[1024];
public synchronized void load()
{
- configFile = configFile.getAbsoluteFile();
+ if (pendingDiskWrites.get() != 0)
+ {
+ LOGGER.log(Level.INFO, "File " + configFile + " not read, because it's not yet written to disk.");
+ return;
+ }
if (!configFile.getParentFile().exists())
{
if (!configFile.getParentFile().mkdirs())
@@ -241,13 +250,12 @@ public class EssentialsConf extends YamlConfiguration
@Override
public synchronized void save(final File file) throws IOException
{
+ //long startTime = System.nanoTime();
if (file == null)
{
throw new IllegalArgumentException("File cannot be null");
}
- Files.createParentDirs(file);
-
final String data = saveToString();
if (data.length() == 0)
@@ -255,32 +263,85 @@ public class EssentialsConf extends YamlConfiguration
return;
}
- if (!configFile.exists())
+ pendingDiskWrites.incrementAndGet();
+
+ EXECUTOR_SERVICE.submit(new WriteRunner(configFile, data, pendingDiskWrites));
+
+ //LOGGER.log(Level.INFO, configFile + " prepared for writing in " + (System.nanoTime() - startTime) + " nsec.");
+ }
+
+
+ private static class WriteRunner implements Runnable
+ {
+ private final File configFile;
+ private final String data;
+ private final AtomicInteger pendingDiskWrites;
+
+ private WriteRunner(final File configFile, final String data, final AtomicInteger pendingDiskWrites)
{
- try
+ this.configFile = configFile;
+ this.data = data;
+ this.pendingDiskWrites = pendingDiskWrites;
+ }
+
+ @Override
+ public void run()
+ {
+ //long startTime = System.nanoTime();
+ synchronized (configFile)
{
- LOGGER.log(Level.INFO, _("creatingEmptyConfig", configFile.toString()));
- if (!configFile.createNewFile())
+ if (pendingDiskWrites.get() > 1)
{
- LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()));
+ // Writes can be skipped, because they are stored in a queue (in the executor).
+ // Only the last is actually written.
+ pendingDiskWrites.decrementAndGet();
+ //LOGGER.log(Level.INFO, configFile + " skipped writing in " + (System.nanoTime() - startTime) + " nsec.");
+ return;
}
- }
- catch (IOException ex)
- {
- LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()), ex);
- }
- }
+ try
+ {
+ Files.createParentDirs(configFile);
+ if (!configFile.exists())
+ {
+ try
+ {
+ LOGGER.log(Level.INFO, _("creatingEmptyConfig", configFile.toString()));
+ if (!configFile.createNewFile())
+ {
+ LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()));
+ return;
+ }
+ }
+ catch (IOException ex)
+ {
+ LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()), ex);
+ return;
+ }
+ }
- final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), UTF8);
- try
- {
- writer.write(data);
- }
- finally
- {
- writer.close();
+ final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(configFile), UTF8);
+
+ try
+ {
+ writer.write(data);
+ }
+ finally
+ {
+ writer.close();
+ }
+ }
+ catch (IOException e)
+ {
+ LOGGER.log(Level.SEVERE, e.getMessage(), e);
+ }
+ finally
+ {
+ //LOGGER.log(Level.INFO, configFile + " written to disk in " + (System.nanoTime() - startTime) + " nsec.");
+ pendingDiskWrites.decrementAndGet();
+ }
+ }
}
}