From 8b4f864f998b035a862e17a0c3e236162aab6cda Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Fri, 14 Nov 2025 22:47:27 +0100 Subject: [PATCH] Add EventCache for efficient retrieval of event groups and teams Signed-off-by: Chaoscaot --- .../src/de/steamwar/data/EventCache.kt | 36 +++++++++++++ .../src/de/steamwar/routes/EventFights.kt | 50 ++++++++++++++++--- .../src/de/steamwar/routes/Events.kt | 7 +-- 3 files changed, 84 insertions(+), 9 deletions(-) create mode 100644 WebsiteBackend/src/de/steamwar/data/EventCache.kt diff --git a/WebsiteBackend/src/de/steamwar/data/EventCache.kt b/WebsiteBackend/src/de/steamwar/data/EventCache.kt new file mode 100644 index 00000000..cbdc1e4f --- /dev/null +++ b/WebsiteBackend/src/de/steamwar/data/EventCache.kt @@ -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 . + */ + +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() + private val teamCache = mutableMapOf() + + 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 } +} \ No newline at end of file diff --git a/WebsiteBackend/src/de/steamwar/routes/EventFights.kt b/WebsiteBackend/src/de/steamwar/routes/EventFights.kt index 82569d40..9edffe3a 100644 --- a/WebsiteBackend/src/de/steamwar/routes/EventFights.kt +++ b/WebsiteBackend/src/de/steamwar/routes/EventFights.kt @@ -20,7 +20,9 @@ package de.steamwar.routes import de.steamwar.ResponseError +import de.steamwar.data.EventCache import de.steamwar.sql.* +import de.steamwar.sql.internal.useDb import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.request.* @@ -41,19 +43,55 @@ data class ResponseEventFight( val ergebnis: Int, val spectatePort: Int?, 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.spielmodus, eventFight.map, - ResponseTeam(Team.byId(eventFight.teamBlue)), - ResponseTeam(Team.byId(eventFight.teamRed)), + cache.getTeam(eventFight.teamBlue), + cache.getTeam(eventFight.teamRed), eventFight.startTime.time, eventFight.ergebnis, eventFight.spectatePort, - eventFight.group.orElse(null)?.let { ResponseGroups(it, short = true) }, - eventFight.hasFinished() + eventFight.groupId?.let { cache.getGroup(it.value) }, + 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, + val redPlayers: List, +) { + 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) }, ) } diff --git a/WebsiteBackend/src/de/steamwar/routes/Events.kt b/WebsiteBackend/src/de/steamwar/routes/Events.kt index e82fc495..1ad54aa2 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Events.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Events.kt @@ -20,6 +20,7 @@ package de.steamwar.routes import de.steamwar.ResponseError +import de.steamwar.data.EventCache import de.steamwar.plugins.SWPermissionCheck import de.steamwar.sql.* import de.steamwar.sql.EventGroup.EventGroupType @@ -113,10 +114,10 @@ data class ExtendedResponseEvent( val referees: List, val relations: List ) { - constructor(event: Event) : this( + constructor(event: Event, cache: EventCache = EventCache()) : this( ResponseEvent(event), - TeamTeilnahme.getTeams(event.eventID).map { ResponseTeam(it) }, - EventGroup.get(event).map { ResponseGroups(it) }, + TeamTeilnahme.getTeams(event.eventID).map { cache.convertTeam(it) }, + EventGroup.get(event).map { cache.convertGroup(it) }, EventFight.getEvent(event.eventID).map { ResponseEventFight(it) }, Referee.get(event.eventID).map { ResponseUser.get(SteamwarUser.byId(it)!!) }, EventRelation.get(event).map { ResponseRelation(it) }