diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java index b7338afa..dc351398 100644 --- a/src/de/steamwar/bungeecore/BungeeCore.java +++ b/src/de/steamwar/bungeecore/BungeeCore.java @@ -25,10 +25,7 @@ import de.steamwar.bungeecore.commands.*; import de.steamwar.bungeecore.comms.SpigotReceiver; import de.steamwar.bungeecore.listeners.*; import de.steamwar.bungeecore.listeners.mods.*; -import de.steamwar.bungeecore.sql.Punishment; -import de.steamwar.bungeecore.sql.Statement; -import de.steamwar.bungeecore.sql.SteamwarUser; -import de.steamwar.bungeecore.sql.Team; +import de.steamwar.bungeecore.sql.*; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; @@ -156,6 +153,7 @@ public class BungeeCore extends Plugin { getProxy().getScheduler().schedule(this, () -> { SteamwarUser.clearCache(); + UserElo.clearCache(); Team.clearCache(); }, 1, 1, TimeUnit.HOURS); diff --git a/src/de/steamwar/bungeecore/sql/UserElo.java b/src/de/steamwar/bungeecore/sql/UserElo.java index c2c4be75..cdfeced7 100644 --- a/src/de/steamwar/bungeecore/sql/UserElo.java +++ b/src/de/steamwar/bungeecore/sql/UserElo.java @@ -19,21 +19,61 @@ package de.steamwar.bungeecore.sql; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; + +import java.util.HashMap; +import java.util.Map; import java.util.Optional; public class UserElo { private UserElo() { } + private static Integer cachedSeason = null; + private static final Map> userEloCache = new HashMap<>(); + private static final Map maxEloCache = new HashMap<>(); + + @AllArgsConstructor + @EqualsAndHashCode + private static class Key { + private final int userId; + private final String gameMode; + } + private static final Statement elo = new Statement("SELECT UserElo FROM Elo WHERE UserID = ? AND GameMode = ? AND Season = ?"); private static final Statement setElo = new Statement("UPDATE UserELo SET Elo = ? WHERE Season = ? AND UserID = ? AND GameMode = ?"); private static final Statement place = new Statement("SELECT COUNT(*) AS Place FROM UserElo WHERE GameMode = ? AND Elo > ? AND Season = ?"); + private static final Statement maxElo = new Statement("SELECT MAX(Elo) AS MaxElo FROM UserElo WHERE Season = ? AND GameMode = ?"); + + private static void clearCacheIfNeeded(int season) { + int currentSeason = Season.getSeason(); + if (currentSeason != season) { + return; + } + if (cachedSeason != null && cachedSeason != currentSeason) { + clearCache(); + cachedSeason = currentSeason; + } + return; + } public static Optional getElo(int userID, String gameMode) { return getElo(Season.getSeason(), userID, gameMode); } public static Optional getElo(int season, int userID, String gameMode) { + clearCacheIfNeeded(season); + if (season == Season.getSeason()) { + Key key = new Key(userID, gameMode); + return userEloCache.computeIfAbsent(key, k -> { + return elo.select(rs -> { + if (rs.next()) + return Optional.of(rs.getInt("UserElo")); + return Optional.empty(); + }); + }); + } return elo.select(rs -> { if (rs.next()) return Optional.of(rs.getInt("Elo")); @@ -41,11 +81,43 @@ public class UserElo { }, userID, gameMode, season); } + public static int getMaxElo(String gameMode) { + return getMaxElo(Season.getSeason(), gameMode); + } + + public static int getMaxElo(int season, String gameMode) { + clearCacheIfNeeded(season); + if (season == Season.getSeason()) { + return maxEloCache.computeIfAbsent(gameMode, gm -> { + return maxElo.select(rs -> { + if (rs.next()) + return rs.getInt("MaxElo"); + return -1; + }); + }); + } + return maxElo.select(rs -> { + if (rs.next()) + return rs.getInt("MaxElo"); + return -1; + }, season, gameMode); + } + public static void setElo(int userId, String gameMode, int elo) { setElo(Season.getSeason(), userId, gameMode, elo); } public static void setElo(int season, int userId, String gameMode, int elo) { + clearCacheIfNeeded(season); + if (season == Season.getSeason()) { + Key key = new Key(userId, gameMode); + userEloCache.put(key, Optional.of(elo)); + maxEloCache.compute(gameMode, (gm, max) -> { + if (max == null || max < elo) + return elo; + return max; + }); + } setElo.update(elo, season, userId, gameMode); } @@ -60,4 +132,9 @@ public class UserElo { return -1; }, gameMode, elo, season); } + + public static void clearCache() { + userEloCache.clear(); + maxEloCache.clear(); + } }