Add EventCache for efficient retrieval of event groups and teams

Signed-off-by: Chaoscaot <max@maxsp.de>
This commit is contained in:
2025-11-14 22:47:27 +01:00
parent f9cb712b07
commit 8b4f864f99
3 changed files with 84 additions and 9 deletions
@@ -0,0 +1,36 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.data
import de.steamwar.routes.ResponseGroups
import de.steamwar.routes.ResponseTeam
import de.steamwar.sql.EventGroup
import de.steamwar.sql.Team
class EventCache {
private val groupCache = mutableMapOf<Int, ResponseGroups>()
private val teamCache = mutableMapOf<Int, ResponseTeam>()
fun getGroup(id: Int): ResponseGroups = groupCache.getOrPut(id) { ResponseGroups(EventGroup.byId(id).get()) }
fun getTeam(id: Int): ResponseTeam = teamCache.getOrPut(id) { ResponseTeam(Team.byId(id)) }
fun convertGroup(group: EventGroup) = ResponseGroups(group).also { groupCache[group.getId()] = it }
fun convertTeam(team: Team) = ResponseTeam(team).also { teamCache[team.teamId] = it }
}
@@ -20,7 +20,9 @@
package de.steamwar.routes package de.steamwar.routes
import de.steamwar.ResponseError import de.steamwar.ResponseError
import de.steamwar.data.EventCache
import de.steamwar.sql.* import de.steamwar.sql.*
import de.steamwar.sql.internal.useDb
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.request.* import io.ktor.server.request.*
@@ -41,19 +43,55 @@ data class ResponseEventFight(
val ergebnis: Int, val ergebnis: Int,
val spectatePort: Int?, val spectatePort: Int?,
val group: ResponseGroups?, val group: ResponseGroups?,
val hasFinished: Boolean val hasFinished: Boolean,
val fightData: FightData? = null
) { ) {
constructor(eventFight: EventFight) : this( constructor(eventFight: EventFight, cache: EventCache = EventCache()) : this(
eventFight.fightID, eventFight.fightID,
eventFight.spielmodus, eventFight.spielmodus,
eventFight.map, eventFight.map,
ResponseTeam(Team.byId(eventFight.teamBlue)), cache.getTeam(eventFight.teamBlue),
ResponseTeam(Team.byId(eventFight.teamRed)), cache.getTeam(eventFight.teamRed),
eventFight.startTime.time, eventFight.startTime.time,
eventFight.ergebnis, eventFight.ergebnis,
eventFight.spectatePort, eventFight.spectatePort,
eventFight.group.orElse(null)?.let { ResponseGroups(it, short = true) }, eventFight.groupId?.let { cache.getGroup(it.value) },
eventFight.hasFinished() eventFight.hasFinished(),
eventFight.fight?.let { FightData(Fight.getById(it)) }
)
}
@Serializable
data class FightData(
val id: Int,
val gamemode: String,
val server: String,
val start: Long,
val duration: Int,
val blueLeader: ResponseUser,
val redLeader: ResponseUser,
val blueSchem: String?,
val redSchem: String?,
val win: String,
val winCondition: String,
val bluePlayers: List<ResponseUser>,
val redPlayers: List<ResponseUser>,
) {
constructor(fight: Fight) : this(
fight.id.value,
fight.gameMode,
fight.server,
fight.startTime.time,
fight.duration,
ResponseUser.get(fight.blueLeader),
ResponseUser.get(fight.redLeader),
fight.blueSchem?.let { SchematicNode.getSchematicNode(it.value)?.name },
fight.redSchem?.let { SchematicNode.getSchematicNode(it.value)?.name },
fight.winner.name,
fight.winCondition,
fight.bluePlayers.map { ResponseUser.get(it.userID) },
fight.redPlayers.map { ResponseUser.get(it.userID) },
) )
} }
@@ -20,6 +20,7 @@
package de.steamwar.routes package de.steamwar.routes
import de.steamwar.ResponseError import de.steamwar.ResponseError
import de.steamwar.data.EventCache
import de.steamwar.plugins.SWPermissionCheck import de.steamwar.plugins.SWPermissionCheck
import de.steamwar.sql.* import de.steamwar.sql.*
import de.steamwar.sql.EventGroup.EventGroupType import de.steamwar.sql.EventGroup.EventGroupType
@@ -113,10 +114,10 @@ data class ExtendedResponseEvent(
val referees: List<ResponseUser>, val referees: List<ResponseUser>,
val relations: List<ResponseRelation> val relations: List<ResponseRelation>
) { ) {
constructor(event: Event) : this( constructor(event: Event, cache: EventCache = EventCache()) : this(
ResponseEvent(event), ResponseEvent(event),
TeamTeilnahme.getTeams(event.eventID).map { ResponseTeam(it) }, TeamTeilnahme.getTeams(event.eventID).map { cache.convertTeam(it) },
EventGroup.get(event).map { ResponseGroups(it) }, EventGroup.get(event).map { cache.convertGroup(it) },
EventFight.getEvent(event.eventID).map { ResponseEventFight(it) }, EventFight.getEvent(event.eventID).map { ResponseEventFight(it) },
Referee.get(event.eventID).map { ResponseUser.get(SteamwarUser.byId(it)!!) }, Referee.get(event.eventID).map { ResponseUser.get(SteamwarUser.byId(it)!!) },
EventRelation.get(event).map { ResponseRelation(it) } EventRelation.get(event).map { ResponseRelation(it) }