Some query optimizations to ServerPlayerContainersQuery:

- Sorted out BaseUser, UserInfo debacle
- GeoInfo query no longer fetches GeoInfo of all servers
- Nickname query no longer fetches Nicknames of all servers
- Ping query no longer fetches Ping of all servers
- Left some comments with what still needs work
This commit is contained in:
Rsl1122 2019-02-10 16:59:30 +02:00
parent 54460bc8e1
commit 7657527e73
10 changed files with 130 additions and 42 deletions

View File

@ -51,11 +51,6 @@ public class UserInfo {
return serverUUID;
}
@Deprecated
public String getName() {
return null;
}
public long getRegistered() {
return registered;
}

View File

@ -45,6 +45,14 @@ import java.util.*;
*/
public class AllPlayerContainersQuery implements Query<List<PlayerContainer>> {
/**
* Create PerServerContainers for each player.
*
* @param sessions Map: Server UUID - Map: Player UUID - List of Sessions
* @param allUserInfo Map: Server UUID - List of Users
* @param allPings Map: Player UUID - List of Ping data
* @return Map: Player UUID - PerServerContainer
*/
static Map<UUID, PerServerContainer> getPerServerData(
Map<UUID, Map<UUID, List<Session>>> sessions,
Map<UUID, List<UserInfo>> allUserInfo,

View File

@ -56,8 +56,8 @@ public class PlayerContainerQuery implements Query<PlayerContainer> {
container.putAll(db.getUsersTable().getUserInformation(uuid));
container.putCachingSupplier(PlayerKeys.GEO_INFO, () -> db.query(GeoInfoQueries.fetchPlayerGeoInformation(uuid)));
container.putCachingSupplier(PlayerKeys.PING, () -> db.query(PingQueries.fetchPlayerPingData(uuid)));
container.putCachingSupplier(PlayerKeys.NICKNAMES, () -> db.query(NicknameQueries.fetchPlayersNicknameData(uuid)));
container.putCachingSupplier(PlayerKeys.PING, () -> db.query(PingQueries.fetchPingDataOfPlayer(uuid)));
container.putCachingSupplier(PlayerKeys.NICKNAMES, () -> db.query(NicknameQueries.fetchNicknameDataOfPlayer(uuid)));
container.putCachingSupplier(PlayerKeys.PER_SERVER, () -> db.query(new PerServerContainerQuery(uuid)));
container.putSupplier(PlayerKeys.BANNED, () -> new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).isBanned());

View File

@ -16,10 +16,7 @@
*/
package com.djrapitops.plan.db.access.queries.containers;
import com.djrapitops.plan.data.container.GeoInfo;
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.container.*;
import com.djrapitops.plan.data.store.containers.PerServerContainer;
import com.djrapitops.plan.data.store.containers.PlayerContainer;
import com.djrapitops.plan.data.store.keys.PlayerKeys;
@ -30,9 +27,7 @@ import com.djrapitops.plan.data.store.objects.Nickname;
import com.djrapitops.plan.data.time.WorldTimes;
import com.djrapitops.plan.db.SQLDB;
import com.djrapitops.plan.db.access.Query;
import com.djrapitops.plan.db.access.queries.objects.GeoInfoQueries;
import com.djrapitops.plan.db.access.queries.objects.NicknameQueries;
import com.djrapitops.plan.db.access.queries.objects.PingQueries;
import com.djrapitops.plan.db.access.queries.objects.*;
import java.util.*;
@ -58,41 +53,50 @@ public class ServerPlayerContainersQuery implements Query<List<PlayerContainer>>
@Override
public List<PlayerContainer> executeQuery(SQLDB db) {
List<PlayerContainer> containers = new ArrayList<>();
List<UserInfo> serverUserInfo = db.getUserInfoTable().getServerUserInfo(serverUUID); // TODO Optimize and sort out
Map<UUID, Integer> timesKicked = db.getUsersTable().getAllTimesKicked(); // TODO Optimize and sort out
Map<UUID, List<GeoInfo>> geoInfo = db.query(GeoInfoQueries.fetchAllGeoInformation()); // TODO Optimize
Map<UUID, List<Ping>> allPings = db.query(PingQueries.fetchAllPingData()); // TODO Optimize
Map<UUID, List<Nickname>> allNicknames = db.query(NicknameQueries.fetchAllNicknameDataByPlayerUUIDs()); // TODO Optimize
Collection<BaseUser> baseUsers = db.query(BaseUserQueries.serverBaseUsers(serverUUID));
Map<UUID, List<GeoInfo>> geoInformation = db.query(GeoInfoQueries.fetchServerGeoInformation(serverUUID));
Map<UUID, List<Nickname>> nicknames = db.query(NicknameQueries.fetchNicknameDataOfServer(serverUUID));
Map<UUID, List<Ping>> pingData = db.query(PingQueries.fetchPingDataOfServer(serverUUID));
// v ------------- Needs work
Map<UUID, List<Session>> sessions = db.getSessionsTable().getSessionInfoOfServer(serverUUID);
Map<UUID, Map<UUID, List<Session>>> map = new HashMap<>();
map.put(serverUUID, sessions);
db.getKillsTable().addKillsToSessions(map); // TODO Optimize
db.getWorldTimesTable().addWorldTimesToSessions(map); // TODO Optimize
Map<UUID, List<UserInfo>> serverUserInfos = Collections.singletonMap(serverUUID, serverUserInfo);
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, allPings
serverSessions, serverUserInfos, pingData
);
// ^ ------------- Needs work
for (UserInfo userInfo : serverUserInfo) {
for (BaseUser user : baseUsers) {
PlayerContainer container = new PlayerContainer();
UUID uuid = userInfo.getPlayerUuid();
// BaseUser
UUID uuid = user.getUuid();
container.putRawData(PlayerKeys.UUID, uuid);
container.putRawData(PlayerKeys.NAME, user.getName());
container.putRawData(PlayerKeys.REGISTERED, user.getRegistered());
container.putRawData(PlayerKeys.KICK_COUNT, user.getTimesKicked());
container.putRawData(PlayerKeys.REGISTERED, userInfo.getRegistered());
container.putRawData(PlayerKeys.NAME, userInfo.getName());
container.putRawData(PlayerKeys.KICK_COUNT, timesKicked.get(uuid));
container.putRawData(PlayerKeys.GEO_INFO, geoInfo.get(uuid));
container.putRawData(PlayerKeys.PING, allPings.get(uuid));
container.putRawData(PlayerKeys.NICKNAMES, allNicknames.get(uuid));
// GeoInfo
container.putRawData(PlayerKeys.GEO_INFO, geoInformation.getOrDefault(uuid, new ArrayList<>()));
// Ping
container.putRawData(PlayerKeys.PING, pingData.get(uuid));
// Nickname, only used for the raw server JSON.
container.putRawData(PlayerKeys.NICKNAMES, nicknames.get(uuid));
// v ------------- Needs work
container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid));
container.putRawData(PlayerKeys.BANNED, userInfo.isBanned());
container.putRawData(PlayerKeys.OPERATOR, userInfo.isOperator());
container.putCachingSupplier(PlayerKeys.SESSIONS, () -> {
List<Session> playerSessions = sessions.getOrDefault(uuid, new ArrayList<>());
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add);
@ -109,6 +113,8 @@ public class ServerPlayerContainersQuery implements Query<List<PlayerContainer>>
);
return worldTimes;
});
container.putSupplier(PlayerKeys.BANNED, () -> PerServerMutator.forContainer(container).isBanned());
container.putSupplier(PlayerKeys.OPERATOR, () -> PerServerMutator.forContainer(container).isOperator());
container.putSupplier(PlayerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen());
@ -116,6 +122,7 @@ public class ServerPlayerContainersQuery implements Query<List<PlayerContainer>>
container.putSupplier(PlayerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(PlayerKeys.PLAYER_KILLS).size());
container.putSupplier(PlayerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
container.putSupplier(PlayerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
// ^ ------------- Needs work
containers.add(container);
}

View File

@ -76,7 +76,7 @@ public class NicknameQueries {
};
}
public static Query<Optional<Nickname>> fetchPlayersLastSeenNickname(UUID playerUUID, UUID serverUUID) {
public static Query<Optional<Nickname>> fetchLastSeenNicknameOfPlayer(UUID playerUUID, UUID serverUUID) {
String subQuery = "SELECT MAX(" + NicknamesTable.LAST_USED + ") FROM " + NicknamesTable.TABLE_NAME +
" WHERE " + NicknamesTable.USER_UUID + "=?" +
" AND " + NicknamesTable.SERVER_UUID + "=?" +
@ -109,7 +109,7 @@ public class NicknameQueries {
};
}
public static Query<List<Nickname>> fetchPlayersNicknameData(UUID playerUUID) {
public static Query<List<Nickname>> fetchNicknameDataOfPlayer(UUID playerUUID) {
String sql = "SELECT " +
NicknamesTable.NICKNAME + ", " +
NicknamesTable.LAST_USED + ", " +
@ -165,4 +165,41 @@ public class NicknameQueries {
}
};
}
/**
* Query database for nickname information of a server.
*
* @param serverUUID UUID the the Plan server.
* @return Map: Player UUID - List of Nicknames on the server.
*/
public static Query<Map<UUID, List<Nickname>>> fetchNicknameDataOfServer(UUID serverUUID) {
String sql = "SELECT " +
NicknamesTable.NICKNAME + ", " +
NicknamesTable.LAST_USED + ", " +
NicknamesTable.USER_UUID + ", " +
NicknamesTable.SERVER_UUID +
" FROM " + NicknamesTable.TABLE_NAME;
return new QueryAllStatement<Map<UUID, List<Nickname>>>(sql, 5000) {
@Override
public Map<UUID, List<Nickname>> processResults(ResultSet set) throws SQLException {
Map<UUID, List<Nickname>> serverMap = new HashMap<>();
while (set.next()) {
UUID serverUUID = UUID.fromString(set.getString(NicknamesTable.SERVER_UUID));
UUID uuid = UUID.fromString(set.getString(NicknamesTable.USER_UUID));
List<Nickname> nicknames = serverMap.getOrDefault(uuid, new ArrayList<>());
nicknames.add(new Nickname(
set.getString(NicknamesTable.NICKNAME),
set.getLong(NicknamesTable.LAST_USED),
serverUUID
));
serverMap.put(uuid, nicknames);
}
return serverMap;
}
};
}
}

View File

@ -85,7 +85,7 @@ public class PingQueries {
* @param playerUUID UUID of the player.
* @return List of Ping entries for this player.
*/
public static Query<List<Ping>> fetchPlayerPingData(UUID playerUUID) {
public static Query<List<Ping>> fetchPingDataOfPlayer(UUID playerUUID) {
String sql = "SELECT * FROM " + PingTable.TABLE_NAME +
" WHERE " + PingTable.USER_UUID + "=?";
@ -114,4 +114,45 @@ public class PingQueries {
}
};
}
public static Query<Map<UUID, List<Ping>>> fetchPingDataOfServer(UUID serverUUID) {
String sql = "SELECT " +
PingTable.DATE + ", " +
PingTable.MAX_PING + ", " +
PingTable.MIN_PING + ", " +
PingTable.AVG_PING + ", " +
PingTable.USER_UUID + ", " +
PingTable.SERVER_UUID +
" FROM " + PingTable.TABLE_NAME +
" WHERE " + PingTable.SERVER_UUID + "=?";
return new QueryStatement<Map<UUID, List<Ping>>>(sql, 100000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public Map<UUID, List<Ping>> processResults(ResultSet set) throws SQLException {
Map<UUID, List<Ping>> userPings = new HashMap<>();
while (set.next()) {
UUID uuid = UUID.fromString(set.getString(PingTable.USER_UUID));
UUID serverUUID = UUID.fromString(set.getString(PingTable.SERVER_UUID));
long date = set.getLong(PingTable.DATE);
double avgPing = set.getDouble(PingTable.AVG_PING);
int minPing = set.getInt(PingTable.MIN_PING);
int maxPing = set.getInt(PingTable.MAX_PING);
List<Ping> pings = userPings.getOrDefault(uuid, new ArrayList<>());
pings.add(new Ping(date, serverUUID,
minPing,
maxPing,
avgPing));
userPings.put(uuid, pings);
}
return userPings;
}
};
}
}

View File

@ -104,7 +104,7 @@ public class NicknameCache implements SubSystem {
private String updateFromDatabase(UUID uuid, String cached) {
try {
Optional<Nickname> latest = dbSystem.getDatabase().query(
NicknameQueries.fetchPlayersLastSeenNickname(uuid, serverInfo.getServerUUID())
NicknameQueries.fetchLastSeenNicknameOfPlayer(uuid, serverInfo.getServerUUID())
);
if (latest.isPresent()) {
cached = latest.get().getName();

View File

@ -135,7 +135,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
@Override
public List<String> getNicknames(UUID playerUUID) {
return db.query(NicknameQueries.fetchPlayersNicknameData(playerUUID)).stream()
return db.query(NicknameQueries.fetchNicknameDataOfPlayer(playerUUID)).stream()
.map(Nickname::getName).collect(Collectors.toList());
}

View File

@ -69,7 +69,7 @@ public class SQLSaveOps extends SQLOps implements SaveOperations {
@Override
protected void performOperations() {
Collection<BaseUser> users = ofUsers.values().stream()
.map(user -> new BaseUser(user.getPlayerUuid(), user.getName(), user.getRegistered(), 0))
.map(user -> new BaseUser(user.getPlayerUuid(), user.getPlayerUuid().toString(), user.getRegistered(), 0))
.collect(Collectors.toSet());
execute(LargeStoreQueries.storeAllCommonUserInformation(users));
}

View File

@ -259,7 +259,7 @@ public abstract class CommonDBTest {
db.executeTransaction(new NicknameStoreTransaction(playerUUID, expected));
commitTest();
List<Nickname> nicknames = db.query(NicknameQueries.fetchPlayersNicknameData(playerUUID));
List<Nickname> nicknames = db.query(NicknameQueries.fetchNicknameDataOfPlayer(playerUUID));
assertEquals(1, nicknames.size());
assertEquals(expected, nicknames.get(0));
}
@ -486,7 +486,7 @@ public abstract class CommonDBTest {
assertFalse(db.query(PlayerFetchQueries.isPlayerRegistered(playerUUID)));
assertFalse(db.query(PlayerFetchQueries.isPlayerRegisteredOnServer(playerUUID, serverUUID)));
assertTrue(db.query(NicknameQueries.fetchPlayersNicknameData(playerUUID)).isEmpty());
assertTrue(db.query(NicknameQueries.fetchNicknameDataOfPlayer(playerUUID)).isEmpty());
assertTrue(db.query(GeoInfoQueries.fetchPlayerGeoInformation(playerUUID)).isEmpty());
assertTrue(sessionsTable.getSessions(playerUUID).isEmpty());
}