Sfoglia il codice sorgente

Optimize SQL side of UUID update

zreed 11 anni fa
parent
commit
8fd9982f69

+ 2 - 0
src/main/java/com/gmail/nossr50/database/DatabaseManager.java

@@ -124,6 +124,8 @@ public interface DatabaseManager {
 
     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.
      *

+ 70 - 4
src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java

@@ -26,6 +26,7 @@ import com.gmail.nossr50.datatypes.skills.AbilityType;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.runnables.database.SQLDatabaseKeepaliveTask;
 import com.gmail.nossr50.runnables.database.SQLReconnectTask;
+import com.gmail.nossr50.runnables.database.UUIDUpdateAsyncTask;
 import com.gmail.nossr50.util.Misc;
 
 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, "
                             + "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, "
-                            + "h.mobhealthbar "
+                            + "h.mobhealthbar, u.uuid "
                             + "FROM " + tablePrefix + "users u "
                             + "JOIN " + tablePrefix + "skills s ON (u.id = s.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
     }
 
+    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.
      * <p/>
@@ -788,7 +835,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
         write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "users` ("
                 + "`id` int(10) unsigned NOT NULL AUTO_INCREMENT,"
                 + "`user` varchar(40) NOT NULL,"
-                + "`uuid` varchar(40) NOT NULL,"
+                + "`uuid` varchar(36) NOT NULL DEFAULT '',"
                 + "`lastlogin` int(32) unsigned NOT NULL,"
                 + "PRIMARY KEY (`id`),"
                 + "UNIQUE KEY `user` (`user`)) DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;");
@@ -992,8 +1039,27 @@ public final class SQLDatabaseManager implements DatabaseManager {
                     break;
 
                 case ADD_UUIDS:
-                    write("ALTER TABLE `" + tablePrefix + "users` ADD `uuid` varchar(50) NOT NULL DEFAULT '';");
-                    return;
+                    try {
+                        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:
                     break;

+ 0 - 5
src/main/java/com/gmail/nossr50/mcMMO.java

@@ -36,7 +36,6 @@ import com.gmail.nossr50.runnables.CheckDateTask;
 import com.gmail.nossr50.runnables.SaveTimerTask;
 import com.gmail.nossr50.runnables.UpdaterResultAsyncTask;
 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.party.PartyAutoKickTask;
 import com.gmail.nossr50.runnables.player.PowerLevelUpdatingTask;
@@ -459,10 +458,6 @@ public class mcMMO extends JavaPlugin {
         long saveIntervalTicks = Config.getInstance().getSaveInterval() * 1200;
         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
         new CleanBackupsTask().runTaskAsynchronously(mcMMO.p);
 

+ 35 - 36
src/main/java/com/gmail/nossr50/runnables/database/UUIDUpdateAsyncTask.java

@@ -1,6 +1,9 @@
 package com.gmail.nossr50.runnables.database;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.UUID;
 
 import org.bukkit.scheduler.BukkitRunnable;
 
@@ -8,68 +11,64 @@ import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.HiddenConfig;
 import com.gmail.nossr50.database.DatabaseManager;
 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.uuid.UUIDFetcher;
 
 public class UUIDUpdateAsyncTask extends BukkitRunnable {
     private mcMMO plugin;
     private static final int MAX_LOOKUP = HiddenConfig.getInstance().getUUIDConvertAmount();
-    private boolean conversionNeeded;
 
-    private DatabaseManager databaseManager;
     private List<String> userNames;
     private int size;
     private int checkedUsers;
     private long startMillis;
 
-    public UUIDUpdateAsyncTask(mcMMO plugin) {
+    public UUIDUpdateAsyncTask(mcMMO plugin, List<String> userNames) {
         this.plugin = plugin;
-        this.conversionNeeded = !mcMMO.getUpgradeManager().shouldUpgrade(UpgradeType.ADD_UUIDS);
-
-        this.databaseManager = mcMMO.getDatabaseManager();
-        this.userNames = databaseManager.getStoredUsers();
-        this.size = userNames.size();
+        this.userNames = userNames;
 
         this.checkedUsers = 0;
-        this.startMillis = System.currentTimeMillis();
-
-        plugin.getLogger().info("Starting to check and update UUIDs, total amount of users: " + size);
     }
 
     @Override
     public void run() {
-        if (!conversionNeeded) {
-            plugin.debug("No need to update database with UUIDs");
-            this.cancel();
-            return;
-        }
 
-        List<String> userNamesSection;
+        startMillis = System.currentTimeMillis();
 
-        if (size > MAX_LOOKUP) {
-            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!");
-        }
+        size = userNames.size();
+
+        plugin.getLogger().info("Starting to check and update UUIDs, total amount of users: " + size);
 
-        for (String userName : userNamesSection) {
-            PlayerProfile profile = databaseManager.loadPlayerProfile(userName, false);
+        List<String> userNamesSection;
+        Map<String,UUID> fetchedUUIDs = new HashMap<String,UUID>();
 
-            checkedUsers++;
+        while (!userNames.isEmpty()) {
 
-            if (profile == null || !profile.isLoaded() || profile.getUniqueId() != null) {
-                continue;
+            if (size > MAX_LOOKUP) {
+                userNamesSection = userNames.subList(size - MAX_LOOKUP, size);
+            }
+            else {
+                userNamesSection = userNames.subList(0, size);
+            }
+
+            try {
+                 fetchedUUIDs.putAll(new UUIDFetcher(userNamesSection).call());
+            }
+            catch (Exception ex) {
+                return;
             }
 
-            new UUIDFetcherRunnable(userName).runTaskAsynchronously(mcMMO.p);
+            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);
+        }
     }
 }