From 8a5461d73bf3e82e90776756a9f8b02d4c17496c Mon Sep 17 00:00:00 2001
From: Me Car <menoc4r@gmail.com>
Date: Thu, 21 Jan 2016 00:44:50 +0900
Subject: [PATCH] Cache UserStats to User.

---
 .../src/main/java/mage/server/ChatManager.java   |  4 ++--
 Mage.Server/src/main/java/mage/server/Main.java  | 10 ++++++++++
 .../src/main/java/mage/server/Session.java       |  6 +++---
 Mage.Server/src/main/java/mage/server/User.java  | 16 ++++++++++++++++
 .../src/main/java/mage/server/UserManager.java   | 14 ++++++--------
 .../java/mage/server/game/GamesRoomImpl.java     |  2 +-
 6 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/Mage.Server/src/main/java/mage/server/ChatManager.java b/Mage.Server/src/main/java/mage/server/ChatManager.java
index f5a5c945cf..ce1b6f5e09 100644
--- a/Mage.Server/src/main/java/mage/server/ChatManager.java
+++ b/Mage.Server/src/main/java/mage/server/ChatManager.java
@@ -110,7 +110,7 @@ public class ChatManager {
         ChatSession chatSession = chatSessions.get(chatId);
         if (chatSession != null) {
             if (message.startsWith("\\") || message.startsWith("/")) {
-                User user = UserManager.getInstance().findUser(userName);
+                User user = UserManager.getInstance().getUserByName(userName);
                 if (user != null && performUserCommand(user, message, chatId)) {
                     return;
                 }
@@ -138,7 +138,7 @@ public class ChatManager {
             if (first > 1) {
                 String userToName = rest.substring(0,first);
                 rest = rest.substring(first + 1).trim();
-                User userTo = UserManager.getInstance().findUser(userToName);
+                User userTo = UserManager.getInstance().getUserByName(userToName);
                 if (userTo != null) {
                     if (!chatSessions.get(chatId).broadcastWhisperToUser(user, userTo, rest)) {
                         message += new StringBuilder("<br/>User ").append(userToName).append(" not found").toString();
diff --git a/Mage.Server/src/main/java/mage/server/Main.java b/Mage.Server/src/main/java/mage/server/Main.java
index 3c6216cff5..34a8d29a1f 100644
--- a/Mage.Server/src/main/java/mage/server/Main.java
+++ b/Mage.Server/src/main/java/mage/server/Main.java
@@ -426,6 +426,11 @@ public class Main {
                     } else {
                         UserStatsRepository.instance.update(new UserStats(builder.build(), table.getEndTimeMs()));
                     }
+                    // UserStats for this player is updated, so refresh it.
+                    User user = UserManager.getInstance().getUserByName(player.getName());
+                    if (user != null) {
+                        user.resetUserStats();
+                    }
                 }
             } else if (table.hasTourney()) {
                 TourneyProto tourney = table.getTourney();
@@ -451,6 +456,11 @@ public class Main {
                     } else {
                         UserStatsRepository.instance.update(new UserStats(builder.build(), table.getEndTimeMs()));
                     }
+                    // UserStats for this player is updated, so refresh it.
+                    User user = UserManager.getInstance().getUserByName(player.getName());
+                    if (user != null) {
+                        user.resetUserStats();
+                    }
                 }
             }
         }
diff --git a/Mage.Server/src/main/java/mage/server/Session.java b/Mage.Server/src/main/java/mage/server/Session.java
index 1ed486fece..69c8ad42fa 100644
--- a/Mage.Server/src/main/java/mage/server/Session.java
+++ b/Mage.Server/src/main/java/mage/server/Session.java
@@ -183,7 +183,7 @@ public class Session {
         User user = UserManager.getInstance().createUser(userName, host);
         boolean reconnect = false;
         if (user == null) {  // user already exists
-            user = UserManager.getInstance().findUser(userName);
+            user = UserManager.getInstance().getUserByName(userName);
             // If authentication is not activated, check the identity using IP address.
             if (ConfigSettings.getInstance().isAuthenticationActivated() || user.getHost().equals(host)) {
                 user.updateLastActivity(null);  // minimizes possible expiration
@@ -218,7 +218,7 @@ public class Session {
         this.isAdmin = true;
         User user = UserManager.getInstance().createUser("Admin", host);
         if (user == null) {
-            user = UserManager.getInstance().findUser("Admin");
+            user = UserManager.getInstance().getUserByName("Admin");
         }
         UserData adminUserData = UserData.getDefaultUserDataView();
         adminUserData.setGroupId(UserGroup.ADMIN.getGroupId());
@@ -230,7 +230,7 @@ public class Session {
     }
 
     public boolean setUserData(String userName, UserData userData) {
-        User user = UserManager.getInstance().findUser(userName);
+        User user = UserManager.getInstance().getUserByName(userName);
         if (user != null) {
             if (user.getUserData() == null || user.getUserData().getGroupId() == UserGroup.DEFAULT.getGroupId()) {
                 user.setUserData(userData);
diff --git a/Mage.Server/src/main/java/mage/server/User.java b/Mage.Server/src/main/java/mage/server/User.java
index 761a647495..d8ef96b5c3 100644
--- a/Mage.Server/src/main/java/mage/server/User.java
+++ b/Mage.Server/src/main/java/mage/server/User.java
@@ -46,6 +46,8 @@ import mage.players.net.UserData;
 import mage.server.draft.DraftSession;
 import mage.server.game.GameManager;
 import mage.server.game.GameSessionPlayer;
+import mage.server.record.UserStats;
+import mage.server.record.UserStatsRepository;
 import mage.server.tournament.TournamentController;
 import mage.server.tournament.TournamentManager;
 import mage.server.tournament.TournamentSession;
@@ -84,6 +86,7 @@ public class User {
     private Date lastActivity;
     private UserState userState;
     private UserData userData;
+    private UserStats userStats;
 
     public User(String userName, String host) {
         this.userId = UUID.randomUUID();
@@ -525,4 +528,17 @@ public class User {
         }
     }
 
+    // getUserStats returns the UserStats for this user. This caches the result, so if the stats is
+    // updated call resetUserStats to refresh it.
+    public UserStats getUserStats() {
+        if (this.userStats == null) {
+            resetUserStats();
+        }
+        return this.userStats;
+    }
+
+    // resetUserStats loads UserStats from DB.
+    public void resetUserStats() {
+        this.userStats = UserStatsRepository.instance.getUser(this.userName);
+    }
 }
diff --git a/Mage.Server/src/main/java/mage/server/UserManager.java b/Mage.Server/src/main/java/mage/server/UserManager.java
index f1d2e1e32b..3306a6ddba 100644
--- a/Mage.Server/src/main/java/mage/server/UserManager.java
+++ b/Mage.Server/src/main/java/mage/server/UserManager.java
@@ -55,6 +55,7 @@ public class UserManager {
     private static final Logger logger = Logger.getLogger(UserManager.class);
 
     private final ConcurrentHashMap<UUID, User> users = new ConcurrentHashMap<>();
+    private final ConcurrentHashMap<String, User> usersByName = new ConcurrentHashMap<>();
     
     private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor();
 
@@ -74,11 +75,12 @@ public class UserManager {
     }
 
     public User createUser(String userName, String host) {
-        if (findUser(userName) != null) {
+        if (getUserByName(userName) != null) {
             return null; //user already exists
         }
         User user = new User(userName, host);
         users.put(user.getId(), user);
+        usersByName.put(userName, user);
         return user;
     }
 
@@ -89,13 +91,8 @@ public class UserManager {
         return null;
     }
 
-    public User findUser(String userName) {
-        for (User user: users.values()) {
-            if (user.getName().equals(userName)) {
-                return user;
-            }
-        }
-        return null;
+    public User getUserByName(String userName) {
+        return usersByName.get(userName);
     }
 
     public Collection<User> getUsers() {
@@ -149,6 +146,7 @@ public class UserManager {
                                 handleException(ex);
                             } finally {
                                 users.remove(userId);
+                                usersByName.remove(user.getName());
                             }
                         }
                     }
diff --git a/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java b/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java
index 1f540b6d91..157b4052b9 100644
--- a/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java
+++ b/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java
@@ -185,7 +185,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
         List<UsersView> users = new ArrayList<>();
         for (User user : UserManager.getInstance().getUsers()) {
             String history = null;
-            UserStats stats = UserStatsRepository.instance.getUser(user.getName());
+            UserStats stats = user.getUserStats();
             if (stats != null) {
                 history = userStatsToString(stats.getProto());
             }