From 517f479ad0d5f7c0bb0e115d6bd60afb48bf3f55 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Tue, 27 Aug 2019 16:43:07 +0300 Subject: [PATCH] Optimized /network Server information queries --- .../plan/data/store/mutators/TPSMutator.java | 8 +++ .../queries/analysis/PlayerCountQueries.java | 54 +++++++++++++++++- .../db/access/queries/objects/TPSQueries.java | 55 ++++++++----------- .../plan/system/json/JSONFactory.java | 34 ++++++++---- 4 files changed, 107 insertions(+), 44 deletions(-) diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java index da862fa2a..c01397206 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java @@ -24,6 +24,7 @@ import com.djrapitops.plan.utilities.html.graphs.line.Point; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -252,4 +253,11 @@ public class TPSMutator { .mapToDouble(TPS::getPlayers) .average().orElse(-1); } + + public Optional getLast() { + if (tpsData.isEmpty()) return Optional.empty(); + // else + tpsData.sort(new TPSComparator()); + return Optional.of(tpsData.get(tpsData.size() - 1)); + } } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/analysis/PlayerCountQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/analysis/PlayerCountQueries.java index bb49887c2..31342d6ef 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/analysis/PlayerCountQueries.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/analysis/PlayerCountQueries.java @@ -26,9 +26,7 @@ import com.djrapitops.plan.db.sql.tables.UsersTable; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.NavigableMap; -import java.util.TreeMap; -import java.util.UUID; +import java.util.*; import static com.djrapitops.plan.db.sql.parsing.Sql.*; @@ -100,6 +98,31 @@ public class PlayerCountQueries { return queryPlayerCount(sql, after, before); } + public static Query> uniquePlayerCounts(long after, long before) { + String sql = SELECT + SessionsTable.SERVER_UUID + ",COUNT(DISTINCT " + SessionsTable.USER_UUID + ") as player_count" + + FROM + SessionsTable.TABLE_NAME + + WHERE + SessionsTable.SESSION_END + "<=?" + + AND + SessionsTable.SESSION_START + ">=?" + + GROUP_BY + UserInfoTable.SERVER_UUID; + + return new QueryStatement>(sql) { + @Override + public void prepare(PreparedStatement statement) throws SQLException { + statement.setLong(1, before); + statement.setLong(2, after); + } + + @Override + public Map processResults(ResultSet set) throws SQLException { + Map byServer = new HashMap<>(); + while (set.next()) { + byServer.put(UUID.fromString(set.getString(UserInfoTable.SERVER_UUID)), set.getInt("player_count")); + } + return byServer; + } + }; + } + /** * Fetch a EpochMs - Count map of unique players on a server. * @@ -233,6 +256,31 @@ public class PlayerCountQueries { return queryPlayerCount(sql, after, before); } + public static Query> newPlayerCounts(long after, long before) { + String sql = SELECT + UserInfoTable.SERVER_UUID + ",COUNT(1) as player_count" + + FROM + UserInfoTable.TABLE_NAME + + WHERE + UserInfoTable.REGISTERED + "<=?" + + AND + UserInfoTable.REGISTERED + ">=?" + + GROUP_BY + UserInfoTable.SERVER_UUID; + + return new QueryStatement>(sql) { + @Override + public void prepare(PreparedStatement statement) throws SQLException { + statement.setLong(1, before); + statement.setLong(2, after); + } + + @Override + public Map processResults(ResultSet set) throws SQLException { + Map byServer = new HashMap<>(); + while (set.next()) { + byServer.put(UUID.fromString(set.getString(UserInfoTable.SERVER_UUID)), set.getInt("player_count")); + } + return byServer; + } + }; + } + /** * Fetch a EpochMs - Count map of new players on a server. * diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/TPSQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/TPSQueries.java index 153e0dc1b..452bd241f 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/TPSQueries.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/TPSQueries.java @@ -63,16 +63,7 @@ public class TPSQueries { List data = new ArrayList<>(); while (set.next()) { - TPS tps = TPSBuilder.get() - .date(set.getLong(DATE)) - .tps(set.getDouble(TPS)) - .playersOnline(set.getInt(PLAYERS_ONLINE)) - .usedCPU(set.getDouble(CPU_USAGE)) - .usedMemory(set.getLong(RAM_USAGE)) - .entities(set.getInt(ENTITIES)) - .chunksLoaded(set.getInt(CHUNKS)) - .freeDiskSpace(set.getLong(FREE_DISK)) - .toTPS(); + com.djrapitops.plan.data.container.TPS tps = extractTPS(set); data.add(tps); } @@ -81,6 +72,19 @@ public class TPSQueries { }; } + public static TPS extractTPS(ResultSet set) throws SQLException { + return TPSBuilder.get() + .date(set.getLong(DATE)) + .tps(set.getDouble(TPS)) + .playersOnline(set.getInt(PLAYERS_ONLINE)) + .usedCPU(set.getDouble(CPU_USAGE)) + .usedMemory(set.getLong(RAM_USAGE)) + .entities(set.getInt(ENTITIES)) + .chunksLoaded(set.getInt(CHUNKS)) + .freeDiskSpace(set.getLong(FREE_DISK)) + .toTPS(); + } + public static Query> fetchTPSDataOfServer(long after, long before, UUID serverUUID) { String sql = Select.all(TABLE_NAME) .where(SERVER_ID + "=" + ServerTable.STATEMENT_SELECT_SERVER_ID) @@ -99,18 +103,7 @@ public class TPSQueries { public List processResults(ResultSet set) throws SQLException { List data = new ArrayList<>(); while (set.next()) { - - TPS tps = TPSBuilder.get() - .date(set.getLong(DATE)) - .tps(set.getDouble(TPS)) - .playersOnline(set.getInt(PLAYERS_ONLINE)) - .usedCPU(set.getDouble(CPU_USAGE)) - .usedMemory(set.getLong(RAM_USAGE)) - .entities(set.getInt(ENTITIES)) - .chunksLoaded(set.getInt(CHUNKS)) - .freeDiskSpace(set.getLong(FREE_DISK)) - .toTPS(); - + TPS tps = extractTPS(set); data.add(tps); } return data; @@ -146,15 +139,15 @@ public class TPSQueries { }; } - public static Query>>> fetchPlayersOnlineOfAllServersBut(long after, long before, UUID leaveOut) { - String sql = SELECT + ServerTable.SERVER_UUID + ',' + DATE + ',' + PLAYERS_ONLINE + + public static Query>> fetchTPSDataOfAllServersBut(long after, long before, UUID leaveOut) { + String sql = SELECT + '*' + FROM + TABLE_NAME + INNER_JOIN + ServerTable.TABLE_NAME + " on " + ServerTable.TABLE_NAME + '.' + ServerTable.SERVER_ID + '=' + SERVER_ID + WHERE + ServerTable.SERVER_UUID + "!=?" + AND + ServerTable.INSTALLED + "=?" + AND + DATE + "?"; - return new QueryStatement>>>(sql, 1000) { + return new QueryStatement>>(sql, 1000) { @Override public void prepare(PreparedStatement statement) throws SQLException { statement.setString(1, leaveOut.toString()); @@ -164,16 +157,16 @@ public class TPSQueries { } @Override - public Map>> processResults(ResultSet set) throws SQLException { - Map>> byServer = new HashMap<>(); - + public Map> processResults(ResultSet set) throws SQLException { + Map> byServer = new HashMap<>(); while (set.next()) { UUID serverUUID = UUID.fromString(set.getString(ServerTable.SERVER_UUID)); - List> ofServer = byServer.getOrDefault(serverUUID, new ArrayList<>()); - ofServer.add(new DateObj<>(set.getLong(DATE), set.getInt(PLAYERS_ONLINE))); + List ofServer = byServer.getOrDefault(serverUUID, new ArrayList<>()); + + ofServer.add(extractTPS(set)); + byServer.put(serverUUID, ofServer); } - return byServer; } }; diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/json/JSONFactory.java b/Plan/common/src/main/java/com/djrapitops/plan/system/json/JSONFactory.java index df93f5de8..b98e6415f 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/json/JSONFactory.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/json/JSONFactory.java @@ -155,26 +155,37 @@ public class JSONFactory { public List> serversAsJSONMaps() { Database db = dbSystem.getDatabase(); - Map serverInformation = db.query(ServerQueries.fetchPlanServerInformation()); long now = System.currentTimeMillis(); long weekAgo = now - TimeUnit.DAYS.toMillis(7L); + long monthAgo = now - TimeUnit.DAYS.toMillis(30L); Formatter year = formatters.yearLong(); Formatter decimals = formatters.decimals(); Formatter timeAmount = formatters.timeAmount(); + Map serverInformation = db.query(ServerQueries.fetchPlanServerInformation()); + UUID proxyUUID = serverInformation.values().stream() + .filter(Server::isProxy) + .findFirst() + .map(Server::getUuid).orElse(null); + + Map> tpsData = db.query( + TPSQueries.fetchTPSDataOfAllServersBut(monthAgo, now, proxyUUID) + ); + Map totalPlayerCounts = db.query(PlayerCountQueries.newPlayerCounts(0, now)); + Map newPlayerCounts = db.query(PlayerCountQueries.newPlayerCounts(monthAgo, now)); + Map uniquePlayerCounts = db.query(PlayerCountQueries.uniquePlayerCounts(monthAgo, now)); + List> servers = new ArrayList<>(); serverInformation.entrySet() .stream() // Sort alphabetically .sorted(Comparator.comparing(entry -> entry.getValue().getIdentifiableName().toLowerCase())) + .filter(entry -> entry.getValue().isNotProxy()) .forEach(entry -> { - if (entry.getValue().isProxy()) return; - UUID serverUUID = entry.getKey(); Map server = new HashMap<>(); server.put("name", entry.getValue().getIdentifiableName()); - // TODO Optimize these queries Optional> recentPeak = db.query(TPSQueries.fetchPeakPlayerCount(serverUUID, now - TimeUnit.DAYS.toMillis(2L))); Optional> allTimePeak = db.query(TPSQueries.fetchAllTimePeakPlayerCount(serverUUID)); server.put("last_peak_date", recentPeak.map(DateObj::getDate).map(year).orElse("-")); @@ -182,17 +193,20 @@ public class JSONFactory { server.put("last_peak_players", recentPeak.map(DateObj::getValue).orElse(0)); server.put("best_peak_players", allTimePeak.map(DateObj::getValue).orElse(0)); - TPSMutator tpsMonth = new TPSMutator(db.query(TPSQueries.fetchTPSDataOfServer(now - TimeUnit.DAYS.toMillis(30L), now, serverUUID))); - server.put("playersOnline", tpsMonth.all().stream().map(tps -> new double[]{tps.getDate(), tps.getPlayers()}).toArray(double[][]::new)); - server.put("players", db.query(PlayerCountQueries.newPlayerCount(0, now, serverUUID))); - server.put("new_players", db.query(PlayerCountQueries.newPlayerCount(weekAgo, now, serverUUID))); - server.put("unique_players", db.query(PlayerCountQueries.uniquePlayerCount(weekAgo, now, serverUUID))); + TPSMutator tpsMonth = new TPSMutator(tpsData.getOrDefault(serverUUID, Collections.emptyList())); + server.put("playersOnline", tpsMonth.all().stream() + .map(tps -> new double[]{tps.getDate(), tps.getPlayers()}) + .toArray(double[][]::new)); + server.put("players", totalPlayerCounts.getOrDefault(serverUUID, 0)); + server.put("new_players", newPlayerCounts.getOrDefault(serverUUID, 0)); + server.put("unique_players", uniquePlayerCounts.getOrDefault(serverUUID, 0)); TPSMutator tpsWeek = tpsMonth.filterDataBetween(weekAgo, now); double averageTPS = tpsWeek.averageTPS(); server.put("avg_tps", averageTPS != -1 ? decimals.apply(averageTPS) : "No data"); server.put("low_tps_spikes", tpsWeek.lowTpsSpikeCount(config.getNumber(DisplaySettings.GRAPH_TPS_THRESHOLD_MED))); server.put("downtime", timeAmount.apply(tpsWeek.serverDownTime())); - Optional online = db.query(TPSQueries.fetchLatestTPSEntryForServer(serverUUID)); + + Optional online = tpsWeek.getLast(); server.put("online", online.isPresent() ? online.get().getDate() >= now - TimeUnit.MINUTES.toMillis(3L) ? online.get().getPlayers() : "Possibly offline"