mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-25 22:56:45 +01:00
Optimize SQL side of UUID update
This commit is contained in:
parent
c5e1a735f9
commit
8fd9982f69
@ -124,6 +124,8 @@ public interface DatabaseManager {
|
|||||||
|
|
||||||
public boolean saveUserUUID(String userName, UUID uuid);
|
public boolean saveUserUUID(String userName, UUID uuid);
|
||||||
|
|
||||||
|
public boolean saveUserUUIDs(Map<String, UUID> user_info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the type of database in use. Custom databases should return CUSTOM.
|
* Retrieve the type of database in use. Custom databases should return CUSTOM.
|
||||||
*
|
*
|
||||||
|
@ -26,6 +26,7 @@ import com.gmail.nossr50.datatypes.skills.AbilityType;
|
|||||||
import com.gmail.nossr50.datatypes.skills.SkillType;
|
import com.gmail.nossr50.datatypes.skills.SkillType;
|
||||||
import com.gmail.nossr50.runnables.database.SQLDatabaseKeepaliveTask;
|
import com.gmail.nossr50.runnables.database.SQLDatabaseKeepaliveTask;
|
||||||
import com.gmail.nossr50.runnables.database.SQLReconnectTask;
|
import com.gmail.nossr50.runnables.database.SQLReconnectTask;
|
||||||
|
import com.gmail.nossr50.runnables.database.UUIDUpdateAsyncTask;
|
||||||
import com.gmail.nossr50.util.Misc;
|
import com.gmail.nossr50.util.Misc;
|
||||||
|
|
||||||
public final class SQLDatabaseManager implements DatabaseManager {
|
public final class SQLDatabaseManager implements DatabaseManager {
|
||||||
@ -543,7 +544,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
|||||||
+ "s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, s.alchemy, "
|
+ "s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, s.alchemy, "
|
||||||
+ "e.taming, e.mining, e.repair, e.woodcutting, e.unarmed, e.herbalism, e.excavation, e.archery, e.swords, e.axes, e.acrobatics, e.fishing, e.alchemy, "
|
+ "e.taming, e.mining, e.repair, e.woodcutting, e.unarmed, e.herbalism, e.excavation, e.archery, e.swords, e.axes, e.acrobatics, e.fishing, e.alchemy, "
|
||||||
+ "c.taming, c.mining, c.repair, c.woodcutting, c.unarmed, c.herbalism, c.excavation, c.archery, c.swords, c.axes, c.acrobatics, c.blast_mining, "
|
+ "c.taming, c.mining, c.repair, c.woodcutting, c.unarmed, c.herbalism, c.excavation, c.archery, c.swords, c.axes, c.acrobatics, c.blast_mining, "
|
||||||
+ "h.mobhealthbar "
|
+ "h.mobhealthbar, u.uuid "
|
||||||
+ "FROM " + tablePrefix + "users u "
|
+ "FROM " + tablePrefix + "users u "
|
||||||
+ "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) "
|
+ "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) "
|
||||||
+ "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) "
|
+ "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) "
|
||||||
@ -620,6 +621,52 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
|||||||
// Problem, nothing was returned
|
// Problem, nothing was returned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean saveUserUUIDs(Map<String,UUID> player_info) {
|
||||||
|
if (!checkConnected()) {
|
||||||
|
// return false
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PreparedStatement statement = null;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
statement = connection.prepareStatement("UPDATE " + tablePrefix + "users SET uuid = ? WHERE user = ?");
|
||||||
|
|
||||||
|
for (Map.Entry<String,UUID> entry : player_info.entrySet()) {
|
||||||
|
statement.setString(1, entry.getValue().toString());
|
||||||
|
statement.setString(2, entry.getKey());
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if ((count % 500) == 0) {
|
||||||
|
statement.executeBatch();
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count != 0) {
|
||||||
|
statement.executeBatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (SQLException ex) {
|
||||||
|
printErrors(ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (statement != null) {
|
||||||
|
try {
|
||||||
|
statement.close();
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check connection status and re-establish if dead or stale.
|
* Check connection status and re-establish if dead or stale.
|
||||||
* <p/>
|
* <p/>
|
||||||
@ -788,7 +835,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
|||||||
write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "users` ("
|
write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "users` ("
|
||||||
+ "`id` int(10) unsigned NOT NULL AUTO_INCREMENT,"
|
+ "`id` int(10) unsigned NOT NULL AUTO_INCREMENT,"
|
||||||
+ "`user` varchar(40) NOT NULL,"
|
+ "`user` varchar(40) NOT NULL,"
|
||||||
+ "`uuid` varchar(40) NOT NULL,"
|
+ "`uuid` varchar(36) NOT NULL DEFAULT '',"
|
||||||
+ "`lastlogin` int(32) unsigned NOT NULL,"
|
+ "`lastlogin` int(32) unsigned NOT NULL,"
|
||||||
+ "PRIMARY KEY (`id`),"
|
+ "PRIMARY KEY (`id`),"
|
||||||
+ "UNIQUE KEY `user` (`user`)) DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;");
|
+ "UNIQUE KEY `user` (`user`)) DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;");
|
||||||
@ -992,8 +1039,27 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ADD_UUIDS:
|
case ADD_UUIDS:
|
||||||
write("ALTER TABLE `" + tablePrefix + "users` ADD `uuid` varchar(50) NOT NULL DEFAULT '';");
|
try {
|
||||||
return;
|
statement.executeQuery("SELECT `uuid` FROM `" + tablePrefix + "users` LIMIT 1");
|
||||||
|
}
|
||||||
|
catch (SQLException ex) {
|
||||||
|
mcMMO.p.getLogger().info("Adding UUIDs to mcMMO MySQL user table...");
|
||||||
|
|
||||||
|
statement.executeQuery("ALTER TABLE `" + tablePrefix + "users` ADD `uuid` varchar(36) NOT NULL DEFAULT ''");
|
||||||
|
|
||||||
|
final List<String> names = new ArrayList<String>();
|
||||||
|
|
||||||
|
resultSet = statement.executeQuery("SELECT `user` FROM `" + tablePrefix + "users`");
|
||||||
|
|
||||||
|
while(resultSet.next()) {
|
||||||
|
names.add(resultSet.getString("user"));
|
||||||
|
}
|
||||||
|
|
||||||
|
new UUIDUpdateAsyncTask(mcMMO.p,names).runTaskAsynchronously(mcMMO.p);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -36,7 +36,6 @@ import com.gmail.nossr50.runnables.CheckDateTask;
|
|||||||
import com.gmail.nossr50.runnables.SaveTimerTask;
|
import com.gmail.nossr50.runnables.SaveTimerTask;
|
||||||
import com.gmail.nossr50.runnables.UpdaterResultAsyncTask;
|
import com.gmail.nossr50.runnables.UpdaterResultAsyncTask;
|
||||||
import com.gmail.nossr50.runnables.backups.CleanBackupsTask;
|
import com.gmail.nossr50.runnables.backups.CleanBackupsTask;
|
||||||
import com.gmail.nossr50.runnables.database.UUIDUpdateAsyncTask;
|
|
||||||
import com.gmail.nossr50.runnables.database.UserPurgeTask;
|
import com.gmail.nossr50.runnables.database.UserPurgeTask;
|
||||||
import com.gmail.nossr50.runnables.party.PartyAutoKickTask;
|
import com.gmail.nossr50.runnables.party.PartyAutoKickTask;
|
||||||
import com.gmail.nossr50.runnables.player.PowerLevelUpdatingTask;
|
import com.gmail.nossr50.runnables.player.PowerLevelUpdatingTask;
|
||||||
@ -459,10 +458,6 @@ public class mcMMO extends JavaPlugin {
|
|||||||
long saveIntervalTicks = Config.getInstance().getSaveInterval() * 1200;
|
long saveIntervalTicks = Config.getInstance().getSaveInterval() * 1200;
|
||||||
new SaveTimerTask().runTaskTimer(this, saveIntervalTicks, saveIntervalTicks);
|
new SaveTimerTask().runTaskTimer(this, saveIntervalTicks, saveIntervalTicks);
|
||||||
|
|
||||||
// Slowly update every entry in the database with UUIDs
|
|
||||||
int uuidConvertInterval = HiddenConfig.getInstance().getUUIDConvertInterval();
|
|
||||||
new UUIDUpdateAsyncTask(this).runTaskTimerAsynchronously(this, uuidConvertInterval * Misc.TICK_CONVERSION_FACTOR, uuidConvertInterval * Misc.TICK_CONVERSION_FACTOR);
|
|
||||||
|
|
||||||
// Cleanup the backups folder
|
// Cleanup the backups folder
|
||||||
new CleanBackupsTask().runTaskAsynchronously(mcMMO.p);
|
new CleanBackupsTask().runTaskAsynchronously(mcMMO.p);
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package com.gmail.nossr50.runnables.database;
|
package com.gmail.nossr50.runnables.database;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
@ -8,68 +11,64 @@ import com.gmail.nossr50.mcMMO;
|
|||||||
import com.gmail.nossr50.config.HiddenConfig;
|
import com.gmail.nossr50.config.HiddenConfig;
|
||||||
import com.gmail.nossr50.database.DatabaseManager;
|
import com.gmail.nossr50.database.DatabaseManager;
|
||||||
import com.gmail.nossr50.datatypes.database.UpgradeType;
|
import com.gmail.nossr50.datatypes.database.UpgradeType;
|
||||||
import com.gmail.nossr50.datatypes.player.PlayerProfile;
|
|
||||||
import com.gmail.nossr50.util.Misc;
|
import com.gmail.nossr50.util.Misc;
|
||||||
|
import com.gmail.nossr50.util.uuid.UUIDFetcher;
|
||||||
|
|
||||||
public class UUIDUpdateAsyncTask extends BukkitRunnable {
|
public class UUIDUpdateAsyncTask extends BukkitRunnable {
|
||||||
private mcMMO plugin;
|
private mcMMO plugin;
|
||||||
private static final int MAX_LOOKUP = HiddenConfig.getInstance().getUUIDConvertAmount();
|
private static final int MAX_LOOKUP = HiddenConfig.getInstance().getUUIDConvertAmount();
|
||||||
private boolean conversionNeeded;
|
|
||||||
|
|
||||||
private DatabaseManager databaseManager;
|
|
||||||
private List<String> userNames;
|
private List<String> userNames;
|
||||||
private int size;
|
private int size;
|
||||||
private int checkedUsers;
|
private int checkedUsers;
|
||||||
private long startMillis;
|
private long startMillis;
|
||||||
|
|
||||||
public UUIDUpdateAsyncTask(mcMMO plugin) {
|
public UUIDUpdateAsyncTask(mcMMO plugin, List<String> userNames) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.conversionNeeded = !mcMMO.getUpgradeManager().shouldUpgrade(UpgradeType.ADD_UUIDS);
|
this.userNames = userNames;
|
||||||
|
|
||||||
this.databaseManager = mcMMO.getDatabaseManager();
|
|
||||||
this.userNames = databaseManager.getStoredUsers();
|
|
||||||
this.size = userNames.size();
|
|
||||||
|
|
||||||
this.checkedUsers = 0;
|
this.checkedUsers = 0;
|
||||||
this.startMillis = System.currentTimeMillis();
|
|
||||||
|
|
||||||
plugin.getLogger().info("Starting to check and update UUIDs, total amount of users: " + size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!conversionNeeded) {
|
|
||||||
plugin.debug("No need to update database with UUIDs");
|
startMillis = System.currentTimeMillis();
|
||||||
this.cancel();
|
|
||||||
return;
|
size = userNames.size();
|
||||||
}
|
|
||||||
|
plugin.getLogger().info("Starting to check and update UUIDs, total amount of users: " + size);
|
||||||
|
|
||||||
List<String> userNamesSection;
|
List<String> userNamesSection;
|
||||||
|
Map<String,UUID> fetchedUUIDs = new HashMap<String,UUID>();
|
||||||
|
|
||||||
if (size > MAX_LOOKUP) {
|
while (!userNames.isEmpty()) {
|
||||||
userNamesSection = userNames.subList(size - MAX_LOOKUP, size);
|
|
||||||
size -= MAX_LOOKUP;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
userNamesSection = userNames.subList(0, size);
|
|
||||||
size = 0;
|
|
||||||
this.cancel();
|
|
||||||
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_UUIDS);
|
|
||||||
plugin.debug("Database updated with UUIDs!");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String userName : userNamesSection) {
|
if (size > MAX_LOOKUP) {
|
||||||
PlayerProfile profile = databaseManager.loadPlayerProfile(userName, false);
|
userNamesSection = userNames.subList(size - MAX_LOOKUP, size);
|
||||||
|
}
|
||||||
checkedUsers++;
|
else {
|
||||||
|
userNamesSection = userNames.subList(0, size);
|
||||||
if (profile == null || !profile.isLoaded() || profile.getUniqueId() != null) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
new UUIDFetcherRunnable(userName).runTaskAsynchronously(mcMMO.p);
|
try {
|
||||||
|
fetchedUUIDs.putAll(new UUIDFetcher(userNamesSection).call());
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkedUsers += userNamesSection.size();
|
||||||
|
|
||||||
|
userNamesSection.clear();
|
||||||
|
|
||||||
|
size = userNames.size();
|
||||||
|
|
||||||
|
Misc.printProgress(checkedUsers, DatabaseManager.progressInterval, startMillis);
|
||||||
}
|
}
|
||||||
|
|
||||||
Misc.printProgress(checkedUsers, DatabaseManager.progressInterval, startMillis);
|
if (mcMMO.getDatabaseManager().saveUserUUIDs(fetchedUUIDs)) {
|
||||||
|
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_UUIDS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user