mirror of
https://github.com/TotalFreedomMC/TF-EssentialsX.git
synced 2025-02-12 04:20:41 +00:00
Delayed write to file (experimental)
This commit is contained in:
parent
e291633ac8
commit
2588e20140
1 changed files with 89 additions and 28 deletions
|
@ -9,6 +9,9 @@ import java.nio.charset.Charset;
|
||||||
import java.nio.charset.CharsetDecoder;
|
import java.nio.charset.CharsetDecoder;
|
||||||
import java.nio.charset.CoderResult;
|
import java.nio.charset.CoderResult;
|
||||||
import java.util.*;
|
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.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
|
@ -24,21 +27,27 @@ import org.bukkit.util.Vector;
|
||||||
public class EssentialsConf extends YamlConfiguration
|
public class EssentialsConf extends YamlConfiguration
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = Logger.getLogger("Minecraft");
|
private static final Logger LOGGER = Logger.getLogger("Minecraft");
|
||||||
private transient File configFile;
|
private final File configFile;
|
||||||
private transient String templateName = null;
|
private String templateName = null;
|
||||||
private transient Class<?> resourceClass = EssentialsConf.class;
|
private Class<?> resourceClass = EssentialsConf.class;
|
||||||
private static final Charset UTF8 = Charset.forName("UTF-8");
|
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)
|
public EssentialsConf(final File configFile)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.configFile = configFile;
|
this.configFile = configFile.getAbsoluteFile();
|
||||||
}
|
}
|
||||||
private final byte[] bytebuffer = new byte[1024];
|
private final byte[] bytebuffer = new byte[1024];
|
||||||
|
|
||||||
public synchronized void load()
|
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().exists())
|
||||||
{
|
{
|
||||||
if (!configFile.getParentFile().mkdirs())
|
if (!configFile.getParentFile().mkdirs())
|
||||||
|
@ -241,13 +250,12 @@ public class EssentialsConf extends YamlConfiguration
|
||||||
@Override
|
@Override
|
||||||
public synchronized void save(final File file) throws IOException
|
public synchronized void save(final File file) throws IOException
|
||||||
{
|
{
|
||||||
|
//long startTime = System.nanoTime();
|
||||||
if (file == null)
|
if (file == null)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("File cannot be null");
|
throw new IllegalArgumentException("File cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
Files.createParentDirs(file);
|
|
||||||
|
|
||||||
final String data = saveToString();
|
final String data = saveToString();
|
||||||
|
|
||||||
if (data.length() == 0)
|
if (data.length() == 0)
|
||||||
|
@ -255,6 +263,45 @@ public class EssentialsConf extends YamlConfiguration
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
this.configFile = configFile;
|
||||||
|
this.data = data;
|
||||||
|
this.pendingDiskWrites = pendingDiskWrites;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
//long startTime = System.nanoTime();
|
||||||
|
synchronized (configFile)
|
||||||
|
{
|
||||||
|
if (pendingDiskWrites.get() > 1)
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Files.createParentDirs(configFile);
|
||||||
|
|
||||||
if (!configFile.exists())
|
if (!configFile.exists())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -263,16 +310,18 @@ public class EssentialsConf extends YamlConfiguration
|
||||||
if (!configFile.createNewFile())
|
if (!configFile.createNewFile())
|
||||||
{
|
{
|
||||||
LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()));
|
LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()), ex);
|
LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()), ex);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), UTF8);
|
final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(configFile), UTF8);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -283,6 +332,18 @@ public class EssentialsConf extends YamlConfiguration
|
||||||
writer.close();
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasProperty(final String path)
|
public boolean hasProperty(final String path)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue