Optimized ServerPlayerContainersQuery PerServerContainer creation

This commit is contained in:
Rsl1122 2019-02-11 17:36:18 +02:00
parent 7657527e73
commit 4d951cea20
5 changed files with 143 additions and 33 deletions

View File

@ -16,8 +16,15 @@
*/
package com.djrapitops.plan.data.store.containers;
import java.util.HashMap;
import java.util.UUID;
import com.djrapitops.plan.data.container.Ping;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.container.UserInfo;
import com.djrapitops.plan.data.store.Key;
import com.djrapitops.plan.data.store.keys.PerServerKeys;
import com.djrapitops.plan.data.store.keys.SessionKeys;
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
import java.util.*;
/**
* Container for data about a player linked to a single server.
@ -26,4 +33,87 @@ import java.util.UUID;
* @see com.djrapitops.plan.data.store.keys.PerServerKeys For Key objects.
*/
public class PerServerContainer extends HashMap<UUID, DataContainer> {
public <T> void putToContainerOfServer(UUID serverUUID, Key<T> key, T value) {
DataContainer container = getOrDefault(serverUUID, new DynamicDataContainer());
container.putRawData(key, value);
put(serverUUID, container);
}
public void putUserInfo(UserInfo userInfo) {
UUID serverUUID = userInfo.getServerUUID();
putToContainerOfServer(serverUUID, PerServerKeys.REGISTERED, userInfo.getRegistered());
putToContainerOfServer(serverUUID, PerServerKeys.BANNED, userInfo.isBanned());
putToContainerOfServer(serverUUID, PerServerKeys.OPERATOR, userInfo.isOperator());
}
public void putUserInfo(Collection<UserInfo> userInformation) {
for (UserInfo userInfo : userInformation) {
putUserInfo(userInfo);
}
}
public void putCalculatingSuppliers() {
for (DataContainer container : values()) {
container.putSupplier(PerServerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen());
container.putSupplier(PerServerKeys.WORLD_TIMES, () -> SessionsMutator.forContainer(container).toTotalWorldTimes());
container.putSupplier(PerServerKeys.PLAYER_DEATHS, () -> SessionsMutator.forContainer(container).toPlayerDeathList());
container.putSupplier(PerServerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList());
container.putSupplier(PerServerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(PerServerKeys.PLAYER_KILLS).size());
container.putSupplier(PerServerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
container.putSupplier(PerServerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
container.putSupplier(PerServerKeys.MOB_DEATH_COUNT, () ->
container.getUnsafe(PerServerKeys.DEATH_COUNT) - container.getUnsafe(PerServerKeys.PLAYER_DEATH_COUNT)
);
}
}
public void putSessions(Collection<Session> sessions) {
if (sessions == null) {
return;
}
for (Session session : sessions) {
putSession(session);
}
}
private void putSession(Session session) {
if (session == null) {
return;
}
UUID serverUUID = session.getUnsafe(SessionKeys.SERVER_UUID);
DataContainer container = getOrDefault(serverUUID, new DynamicDataContainer());
if (!container.supports(PerServerKeys.SESSIONS)) {
container.putRawData(PerServerKeys.SESSIONS, new ArrayList<>());
}
container.getUnsafe(PerServerKeys.SESSIONS).add(session);
put(serverUUID, container);
}
public void putPing(List<Ping> pings) {
if (pings == null) {
return;
}
for (Ping ping : pings) {
putPing(ping);
}
}
private void putPing(Ping ping) {
if (ping == null) {
return;
}
UUID serverUUID = ping.getServerUUID();
DataContainer container = getOrDefault(serverUUID, new DynamicDataContainer());
if (!container.supports(PerServerKeys.PING)) {
container.putRawData(PerServerKeys.PING, new ArrayList<>());
}
container.getUnsafe(PerServerKeys.PING).add(ping);
put(serverUUID, container);
}
}

View File

@ -53,7 +53,7 @@ public class AllPlayerContainersQuery implements Query<List<PlayerContainer>> {
* @param allPings Map: Player UUID - List of Ping data
* @return Map: Player UUID - PerServerContainer
*/
static Map<UUID, PerServerContainer> getPerServerData(
private Map<UUID, PerServerContainer> getPerServerData(
Map<UUID, Map<UUID, List<Session>>> sessions,
Map<UUID, List<UserInfo>> allUserInfo,
Map<UUID, List<Ping>> allPings
@ -84,8 +84,8 @@ public class AllPlayerContainersQuery implements Query<List<PlayerContainer>> {
Map<UUID, List<Session>> serverUserSessions = entry.getValue();
for (Map.Entry<UUID, List<Session>> sessionEntry : serverUserSessions.entrySet()) {
UUID uuid = sessionEntry.getKey();
PerServerContainer perServerContainer = perServerContainers.getOrDefault(uuid, new PerServerContainer());
UUID playerUUID = sessionEntry.getKey();
PerServerContainer perServerContainer = perServerContainers.getOrDefault(playerUUID, new PerServerContainer());
DataContainer container = perServerContainer.getOrDefault(serverUUID, new SupplierDataContainer());
List<Session> serverSessions = sessionEntry.getValue();
@ -103,7 +103,7 @@ public class AllPlayerContainersQuery implements Query<List<PlayerContainer>> {
container.getUnsafe(PerServerKeys.DEATH_COUNT) - container.getUnsafe(PerServerKeys.PLAYER_DEATH_COUNT)
);
perServerContainer.put(serverUUID, container);
perServerContainers.put(uuid, perServerContainer);
perServerContainers.put(playerUUID, perServerContainer);
}
}

View File

@ -23,7 +23,6 @@ import com.djrapitops.plan.data.store.containers.DataContainer;
import com.djrapitops.plan.data.store.containers.PerServerContainer;
import com.djrapitops.plan.data.store.containers.SupplierDataContainer;
import com.djrapitops.plan.data.store.keys.PerServerKeys;
import com.djrapitops.plan.data.store.keys.PlayerKeys;
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
import com.djrapitops.plan.db.SQLDB;
import com.djrapitops.plan.db.access.Query;
@ -108,25 +107,14 @@ public class PerServerContainerQuery implements Query<PerServerContainer> {
matchingEntrySet(PerServerKeys.LAST_SEEN, PerServerAggregateQueries.lastSeenOnServers(playerUUID), db, container);
}
private void userInformation(SQLDB db, PerServerContainer perServerContainer) {
private void userInformation(SQLDB db, PerServerContainer container) {
List<UserInfo> userInformation = db.query(UserInfoQueries.fetchUserInformationOfUser(playerUUID));
for (UserInfo userInfo : userInformation) {
UUID serverUUID = userInfo.getServerUUID();
placeToPerServerContainer(serverUUID, PlayerKeys.REGISTERED, userInfo.getRegistered(), perServerContainer);
placeToPerServerContainer(serverUUID, PlayerKeys.BANNED, userInfo.isBanned(), perServerContainer);
placeToPerServerContainer(serverUUID, PlayerKeys.OPERATOR, userInfo.isOperator(), perServerContainer);
}
container.putUserInfo(userInformation);
}
private <T> void matchingEntrySet(Key<T> key, Query<Map<UUID, T>> map, SQLDB db, PerServerContainer container) {
for (Map.Entry<UUID, T> lastSeen : db.query(map).entrySet()) {
placeToPerServerContainer(lastSeen.getKey(), key, lastSeen.getValue(), container);
for (Map.Entry<UUID, T> entry : db.query(map).entrySet()) {
container.putToContainerOfServer(entry.getKey(), key, entry.getValue());
}
}
private <T> void placeToPerServerContainer(UUID serverUUID, Key<T> key, T value, PerServerContainer perServerContainer) {
DataContainer container = perServerContainer.getOrDefault(serverUUID, new SupplierDataContainer());
container.putRawData(key, value);
perServerContainer.put(serverUUID, container);
}
}

View File

@ -50,11 +50,41 @@ public class ServerPlayerContainersQuery implements Query<List<PlayerContainer>>
this.serverUUID = serverUUID;
}
/**
* Create PerServerContainers for each player.
*
* @param userInformation Map: Player UUID - UserInfo of this server
* @param sessions Map: Player UUID - List of Sessions of this server
* @param ping Map: Player UUID - List of Ping data of this server
* @return Map: Player UUID - PerServerContainer
*/
private static Map<UUID, PerServerContainer> getPerServerData(
Map<UUID, UserInfo> userInformation,
Map<UUID, List<Session>> sessions,
Map<UUID, List<Ping>> ping
) {
Map<UUID, PerServerContainer> perServerContainers = new HashMap<>();
for (Map.Entry<UUID, UserInfo> entry : userInformation.entrySet()) {
UUID playerUUID = entry.getKey();
PerServerContainer perServerContainer = perServerContainers.getOrDefault(playerUUID, new PerServerContainer());
perServerContainer.putUserInfo(entry.getValue()); // Information found withing UserInfo
perServerContainer.putSessions(sessions.get(playerUUID)); // Session list
perServerContainer.putPing(ping.get(playerUUID)); // Ping list
perServerContainer.putCalculatingSuppliers(); // Derivative values
perServerContainers.put(playerUUID, perServerContainer);
}
return perServerContainers;
}
@Override
public List<PlayerContainer> executeQuery(SQLDB db) {
List<PlayerContainer> containers = new ArrayList<>();
Collection<BaseUser> baseUsers = db.query(BaseUserQueries.serverBaseUsers(serverUUID));
Collection<BaseUser> baseUsers = db.query(BaseUserQueries.fetchServerBaseUsers(serverUUID));
Map<UUID, List<GeoInfo>> geoInformation = db.query(GeoInfoQueries.fetchServerGeoInformation(serverUUID));
Map<UUID, List<Nickname>> nicknames = db.query(NicknameQueries.fetchNicknameDataOfServer(serverUUID));
@ -66,16 +96,16 @@ public class ServerPlayerContainersQuery implements Query<List<PlayerContainer>>
map.put(serverUUID, sessions);
db.getKillsTable().addKillsToSessions(map); // TODO Optimize
db.getWorldTimesTable().addWorldTimesToSessions(map); // TODO Optimize
Map<UUID, List<UserInfo>> serverUserInfos = Collections.singletonMap(serverUUID, // TODO Optimize
new ArrayList<>(db.query(UserInfoQueries.fetchUserInformationOfServer(serverUUID)).values())
);
Map<UUID, Map<UUID, List<Session>>> serverSessions = Collections.singletonMap(serverUUID, sessions);
Map<UUID, PerServerContainer> perServerInfo = AllPlayerContainersQuery.getPerServerData(
serverSessions, serverUserInfos, pingData
);
// ^ ------------- Needs work
Map<UUID, UserInfo> userInformation = db.query(UserInfoQueries.fetchUserInformationOfServer(serverUUID));
Map<UUID, PerServerContainer> perServerInfo = getPerServerData(
userInformation,
sessions,
pingData
);
for (BaseUser user : baseUsers) {
PlayerContainer container = new PlayerContainer();
@ -95,8 +125,10 @@ public class ServerPlayerContainersQuery implements Query<List<PlayerContainer>>
// Nickname, only used for the raw server JSON.
container.putRawData(PlayerKeys.NICKNAMES, nicknames.get(uuid));
// v ------------- Needs work
// PerServerContainer
container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid));
// v ------------- Needs work
container.putCachingSupplier(PlayerKeys.SESSIONS, () -> {
List<Session> playerSessions = sessions.getOrDefault(uuid, new ArrayList<>());
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add);

View File

@ -67,7 +67,7 @@ public class BaseUserQueries {
};
}
public static Query<Collection<BaseUser>> serverBaseUsers(UUID serverUUID) {
public static Query<Collection<BaseUser>> fetchServerBaseUsers(UUID serverUUID) {
String sql = "SELECT " +
UsersTable.TABLE_NAME + "." + UsersTable.USER_UUID + ", " +
UsersTable.USER_NAME + ", " +