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 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(); public abstract boolean load();
} }

View File

@ -6,7 +6,6 @@ import com.massivecraft.factions.FLocation;
import com.massivecraft.factions.P; import com.massivecraft.factions.P;
import com.massivecraft.factions.zcore.persist.MemoryBoard; import com.massivecraft.factions.zcore.persist.MemoryBoard;
import com.massivecraft.factions.zcore.util.DiscUtil; import com.massivecraft.factions.zcore.util.DiscUtil;
import org.bukkit.Bukkit;
import java.io.File; import java.io.File;
import java.lang.reflect.Type; import java.lang.reflect.Type;
@ -63,34 +62,12 @@ public class JSONBoard extends MemoryBoard {
} }
} }
public boolean forceSave() { public void forceSave() {
return forceSave(true); forceSave(true);
} }
public boolean forceSave(boolean sync) { public void forceSave(boolean sync) {
if (sync) { DiscUtil.writeCatch(file, P.p.gson.toJson(dumpAsSaveFormat()), 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 boolean load() { public boolean load() {

View File

@ -62,20 +62,11 @@ public class JSONFPlayers extends MemoryFPlayers {
} }
} }
if (sync) { saveCore(file, entitiesThatShouldBeSaved, sync);
saveCore(file, entitiesThatShouldBeSaved);
} else {
Bukkit.getScheduler().runTaskAsynchronously(P.p, new Runnable() {
@Override
public void run() {
saveCore(file, entitiesThatShouldBeSaved);
}
});
}
} }
private boolean saveCore(File target, Map<String, JSONFPlayer> data) { private boolean saveCore(File target, Map<String, JSONFPlayer> data, boolean sync) {
return DiscUtil.writeCatch(target, this.gson.toJson(data)); return DiscUtil.writeCatch(target, this.gson.toJson(data), sync);
} }
public void load() { public void load() {
@ -126,7 +117,7 @@ public class JSONFPlayers extends MemoryFPlayers {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); 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()); Bukkit.getLogger().log(Level.INFO, "Backed up your old data at " + file.getAbsolutePath());
// Start fetching those UUIDs // 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, "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, ", ")); 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 // flatfile
Bukkit.getLogger().log(Level.INFO, "Done converting players.json to UUID."); 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); entitiesThatShouldBeSaved.put(entity.getId(), (JSONFaction) entity);
} }
if (sync) { saveCore(file, entitiesThatShouldBeSaved, sync);
saveCore(file, entitiesThatShouldBeSaved);
} else {
Bukkit.getScheduler().runTaskAsynchronously(P.p, new Runnable() {
@Override
public void run() {
saveCore(file, entitiesThatShouldBeSaved);
}
});
}
} }
private boolean saveCore(File target, Map<String, JSONFaction> entities) { private boolean saveCore(File target, Map<String, JSONFaction> entities, boolean sync) {
return DiscUtil.writeCatch(target, this.gson.toJson(entities)); return DiscUtil.writeCatch(target, this.gson.toJson(entities), sync);
} }
public void load() { public void load() {
@ -129,7 +120,7 @@ public class JSONFactions extends MemoryFactions {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); 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, "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."); 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."); Bukkit.getLogger().log(Level.INFO, "Done converting factions.json to UUID.");
} }
return data; return data;

View File

@ -1,6 +1,13 @@
package com.massivecraft.factions.zcore.util; package com.massivecraft.factions.zcore.util;
import com.massivecraft.factions.P;
import org.bukkit.Bukkit;
import java.io.*; 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 { public class DiscUtil {
@ -14,6 +21,7 @@ public class DiscUtil {
// BYTE // BYTE
// -------------------------------------------- // // -------------------------------------------- //
public static byte[] readBytes(File file) throws IOException { public static byte[] readBytes(File file) throws IOException {
int length = (int) file.length(); int length = (int) file.length();
byte[] output = new byte[length]; byte[] output = new byte[length];
@ -48,13 +56,52 @@ public class DiscUtil {
// CATCH // CATCH
// -------------------------------------------- // // -------------------------------------------- //
public static boolean writeCatch(File file, String content) { private static HashMap<String, Lock> locks = new HashMap<String, Lock>();
try {
write(file, content); public static boolean writeCatch(final File file, final String content, boolean sync) {
return true; final byte[] bytes = utf8(content);
} catch (Exception e) { String name = file.getName();
return false; 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) { public static String readCatch(File file) {

View File

@ -100,7 +100,7 @@ public class Persist {
} }
public boolean save(Object instance, File file) { 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 // LOAD BY CLASS