Improve concurrency with help from @evilmidget38

This commit is contained in:
drtshock 2015-08-07 15:03:22 -05:00
parent 1a94e89558
commit 3db1d5fdb3
6 changed files with 70 additions and 64 deletions

View File

@ -78,9 +78,9 @@ public abstract class Board {
*/
public abstract ArrayList<String> getMap(Faction faction, FLocation flocation, double inDegrees);
public abstract boolean forceSave();
public abstract void forceSave();
public abstract boolean forceSave(boolean sync);
public abstract void forceSave(boolean sync);
public abstract boolean load();
}

View File

@ -6,7 +6,6 @@ import com.massivecraft.factions.FLocation;
import com.massivecraft.factions.P;
import com.massivecraft.factions.zcore.persist.MemoryBoard;
import com.massivecraft.factions.zcore.util.DiscUtil;
import org.bukkit.Bukkit;
import java.io.File;
import java.lang.reflect.Type;
@ -63,34 +62,12 @@ public class JSONBoard extends MemoryBoard {
}
}
public boolean forceSave() {
return forceSave(true);
public void forceSave() {
forceSave(true);
}
public boolean forceSave(boolean sync) {
if (sync) {
try {
DiscUtil.write(file, P.p.gson.toJson(dumpAsSaveFormat()));
} catch (Exception e) {
e.printStackTrace();
P.p.log("Failed to save the board to disk.");
return false;
}
} else {
Bukkit.getScheduler().runTaskAsynchronously(P.p, new Runnable() {
@Override
public void run() {
try {
DiscUtil.write(file, P.p.gson.toJson(dumpAsSaveFormat()));
} catch (Exception e) {
e.printStackTrace();
P.p.log("Failed to save the board to disk.");
}
}
});
}
return true;
public void forceSave(boolean sync) {
DiscUtil.writeCatch(file, P.p.gson.toJson(dumpAsSaveFormat()), sync);
}
public boolean load() {

View File

@ -62,20 +62,11 @@ public class JSONFPlayers extends MemoryFPlayers {
}
}
if (sync) {
saveCore(file, entitiesThatShouldBeSaved);
} else {
Bukkit.getScheduler().runTaskAsynchronously(P.p, new Runnable() {
@Override
public void run() {
saveCore(file, entitiesThatShouldBeSaved);
}
});
}
saveCore(file, entitiesThatShouldBeSaved, sync);
}
private boolean saveCore(File target, Map<String, JSONFPlayer> data) {
return DiscUtil.writeCatch(target, this.gson.toJson(data));
private boolean saveCore(File target, Map<String, JSONFPlayer> data, boolean sync) {
return DiscUtil.writeCatch(target, this.gson.toJson(data), sync);
}
public void load() {
@ -126,7 +117,7 @@ public class JSONFPlayers extends MemoryFPlayers {
} catch (IOException e) {
e.printStackTrace();
}
saveCore(file, (Map<String, JSONFPlayer>) data);
saveCore(file, (Map<String, JSONFPlayer>) data, true);
Bukkit.getLogger().log(Level.INFO, "Backed up your old data at " + file.getAbsolutePath());
// Start fetching those UUIDs
@ -170,7 +161,7 @@ public class JSONFPlayers extends MemoryFPlayers {
Bukkit.getLogger().log(Level.INFO, "While converting we found names that either don't have a UUID or aren't players and removed them from storage.");
Bukkit.getLogger().log(Level.INFO, "The following names were detected as being invalid: " + StringUtils.join(invalidList, ", "));
}
saveCore(this.file, (Map<String, JSONFPlayer>) data); // Update the
saveCore(this.file, (Map<String, JSONFPlayer>) data, true); // Update the
// flatfile
Bukkit.getLogger().log(Level.INFO, "Done converting players.json to UUID.");
}

View File

@ -62,20 +62,11 @@ public class JSONFactions extends MemoryFactions {
entitiesThatShouldBeSaved.put(entity.getId(), (JSONFaction) entity);
}
if (sync) {
saveCore(file, entitiesThatShouldBeSaved);
} else {
Bukkit.getScheduler().runTaskAsynchronously(P.p, new Runnable() {
@Override
public void run() {
saveCore(file, entitiesThatShouldBeSaved);
}
});
}
saveCore(file, entitiesThatShouldBeSaved, sync);
}
private boolean saveCore(File target, Map<String, JSONFaction> entities) {
return DiscUtil.writeCatch(target, this.gson.toJson(entities));
private boolean saveCore(File target, Map<String, JSONFaction> entities, boolean sync) {
return DiscUtil.writeCatch(target, this.gson.toJson(entities), sync);
}
public void load() {
@ -129,7 +120,7 @@ public class JSONFactions extends MemoryFactions {
} catch (IOException e) {
e.printStackTrace();
}
saveCore(file, (Map<String, JSONFaction>) data);
saveCore(file, (Map<String, JSONFaction>) data, true);
Bukkit.getLogger().log(Level.INFO, "Backed up your old data at " + file.getAbsolutePath());
Bukkit.getLogger().log(Level.INFO, "Please wait while Factions converts " + needsUpdate + " old player names to UUID. This may take a while.");
@ -189,7 +180,7 @@ public class JSONFactions extends MemoryFactions {
}
}
saveCore(this.file, (Map<String, JSONFaction>) data); // Update the flatfile
saveCore(this.file, (Map<String, JSONFaction>) data, true); // Update the flatfile
Bukkit.getLogger().log(Level.INFO, "Done converting factions.json to UUID.");
}
return data;

View File

@ -1,6 +1,13 @@
package com.massivecraft.factions.zcore.util;
import com.massivecraft.factions.P;
import org.bukkit.Bukkit;
import java.io.*;
import java.util.HashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class DiscUtil {
@ -14,6 +21,7 @@ public class DiscUtil {
// BYTE
// -------------------------------------------- //
public static byte[] readBytes(File file) throws IOException {
int length = (int) file.length();
byte[] output = new byte[length];
@ -48,13 +56,52 @@ public class DiscUtil {
// CATCH
// -------------------------------------------- //
public static boolean writeCatch(File file, String content) {
try {
write(file, content);
return true;
} catch (Exception e) {
return false;
private static HashMap<String, Lock> locks = new HashMap<String, Lock>();
public static boolean writeCatch(final File file, final String content, boolean sync) {
final byte[] bytes = utf8(content);
String name = file.getName();
final Lock lock;
// Create lock for each file if there isn't already one.
if (locks.containsKey(name)) {
lock = locks.get(name);
} else {
ReadWriteLock rwl = new ReentrantReadWriteLock();
lock = rwl.writeLock();
locks.put(name, lock);
}
if (sync) {
lock.lock();
try {
FileOutputStream out = new FileOutputStream(file);
out.write(bytes);
out.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} else {
Bukkit.getScheduler().runTaskAsynchronously(P.p, new Runnable() {
@Override
public void run() {
lock.lock();
try {
FileOutputStream out = new FileOutputStream(file);
out.write(bytes);
out.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
});
}
return true; // don't really care but for some reason this is a boolean.
}
public static String readCatch(File file) {

View File

@ -100,7 +100,7 @@ public class Persist {
}
public boolean save(Object instance, File file) {
return DiscUtil.writeCatch(file, p.gson.toJson(instance));
return DiscUtil.writeCatch(file, p.gson.toJson(instance), true);
}
// LOAD BY CLASS