Ranked #306
@ -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);
|
||||
|
||||
|
@ -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<Key, Optional<Integer>> userEloCache = new HashMap<>();
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
|
||||
private static final Map<String, Integer> 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 = ?");
|
||||
Lixfel markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Mach es doch wie in der SchemElo und gib die Default-Elo zurück, wenn es keine gibt... Falls du eine Funktion brauchst, wo es relevant ist, ob überhaupt eine exisitiert, dann habe das doch als 2 verschiedene Funktionen. Damit würde dann z.B. der FightEndsHandler nichts mehr von der Default-Elo wissen müssen Mach es doch wie in der SchemElo und gib die Default-Elo zurück, wenn es keine gibt... Falls du eine Funktion brauchst, wo es relevant ist, ob überhaupt eine exisitiert, dann habe das doch als 2 verschiedene Funktionen. Damit würde dann z.B. der FightEndsHandler nichts mehr von der Default-Elo wissen müssen
YoyoNow
hat
Ist das so in Ordnung wie ich das gemacht habe? Ist das so in Ordnung wie ich das gemacht habe?
|
||||
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();
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Du clearst den Cache eh schon stündlich, das ist häufig genug auch für Seasonänderungen. Du clearst den Cache eh schon stündlich, das ist häufig genug auch für Seasonänderungen.
|
||||
if (currentSeason != season) {
|
||||
return;
|
||||
}
|
||||
if (cachedSeason != null && cachedSeason != currentSeason) {
|
||||
clearCache();
|
||||
cachedSeason = currentSeason;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public static Optional<Integer> getElo(int userID, String gameMode) {
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Wenn hier eh schon mit Integer gearbeitet wird, kann man das Optional auch weglassen... Wenn hier eh schon mit Integer gearbeitet wird, kann man das Optional auch weglassen...
YoyoNow
hat
Würde ich ungern, weil so kann man darauf mit Würde ich ungern, weil so kann man darauf mit `.orElse()` ziemlich gut einen default direkt auswählen.
YoyoNow
hat
Und halt Optional.empty() als es gibt keinen wert in der db wählen, macht es für die emblem berechnung angenehmer, als mit einem spezial value zu arbeiten. Und halt Optional.empty() als es gibt keinen wert in der db wählen, macht es für die emblem berechnung angenehmer, als mit einem spezial value zu arbeiten.
|
||||
return getElo(Season.getSeason(), userID, gameMode);
|
||||
}
|
||||
|
||||
public static Optional<Integer> getElo(int season, int userID, String gameMode) {
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Wie häufig/welche Ingame-Teile werden jemals NICHT die aktuelle Season abfragen? Wie häufig/welche Ingame-Teile werden jemals NICHT die aktuelle Season abfragen?
YoyoNow
hat
gute Frage, glaube nichts also raus damit. gute Frage, glaube nichts also raus damit.
|
||||
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;
|
||||
});
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Wann ist season hier != currentSeason? Wann ist season hier != currentSeason?
|
||||
});
|
||||
}
|
||||
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;
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Selbe Frage Selbe Frage
|
||||
});
|
||||
}
|
||||
setElo.update(elo, season, userId, gameMode);
|
||||
}
|
||||
|
||||
@ -60,4 +132,9 @@ public class UserElo {
|
||||
return -1;
|
||||
}, gameMode, elo, season);
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
. .
|
||||
userEloCache.clear();
|
||||
maxEloCache.clear();
|
||||
}
|
||||
}
|
||||
|
Da lieber eine Map<Map<>>, das bläst sich dann weniger auf.
Wie meinst du das genau?
HashMaps brauchen zur Kollisionsvermeidung immer Freiraum. Je kleiner die HashMaps bleiben, desto besser.
Würdest du dann GameMode UserId oder UserId GameMode als reihenfolge wählen?
Definitiv Map<GameMode, Map<User, >>