From f5959925aa7e076383a75f68b02a2c5e1ff784aa Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Mon, 23 Dec 2024 18:00:06 -0500 Subject: [PATCH] [O] Handle ranking with binary search --- .../samnyan/aqua/net/games/GameApiController.kt | 14 +++++++++++--- src/main/java/icu/samnyan/aqua/net/games/Models.kt | 2 -- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/icu/samnyan/aqua/net/games/GameApiController.kt b/src/main/java/icu/samnyan/aqua/net/games/GameApiController.kt index 9680f59b..59152ba2 100644 --- a/src/main/java/icu/samnyan/aqua/net/games/GameApiController.kt +++ b/src/main/java/icu/samnyan/aqua/net/games/GameApiController.kt @@ -35,9 +35,11 @@ abstract class GameApiController(val name: String, userDataClass: playlogRepo.findByUserCardExtId(card.extId) } - // Pair>> + // List>> private var rankingCache: List> = emptyList() private var rankingCacheLock = ReentrantLock() + // Sorted index List = Rank + private var rankingSortedIndex: List = emptyList() @API("ranking") fun ranking(@RP token: String?): List { val time = millis() @@ -100,7 +102,8 @@ abstract class GameApiController(val name: String, userDataClass: username = it[8]?.toString() ?: "user${it[0]}" ) } - logger.info("Ranking computed in ${millis() - time}ms") + rankingSortedIndex = rankingCache.filter { !it.l }.map { it.r.rating }.reversed() + logger.info("Ranking for $name computed in ${millis() - time}ms") } @API("playlog") @@ -153,10 +156,15 @@ abstract class GameApiController(val name: String, userDataClass: } } + // Find serverRank by binary-searching in the rankingSortedIndex to find the minimal index that + // is greater than or equal to the user's rating + var serverRank = rankingSortedIndex.binarySearch(user.playerRating).let { if (it < 0) -it - 1 else it + 1 } + serverRank = rankingSortedIndex.size - serverRank + return GenericGameSummary( name = user.userName, aquaUser = card.aquaUser?.publicFields, - serverRank = userDataRepo.getRanking(user.playerRating), + serverRank = serverRank.long, accuracy = plays.acc(), rating = user.playerRating, ratingHighest = user.highestRating, diff --git a/src/main/java/icu/samnyan/aqua/net/games/Models.kt b/src/main/java/icu/samnyan/aqua/net/games/Models.kt index fd7f68c3..15f0e1d3 100644 --- a/src/main/java/icu/samnyan/aqua/net/games/Models.kt +++ b/src/main/java/icu/samnyan/aqua/net/games/Models.kt @@ -121,8 +121,6 @@ open class BaseEntity( interface GenericUserDataRepo : JpaRepository { fun findByCard(card: Card): T? fun findByCard_ExtId(extId: Long): Optional - @Query("select count(*) from #{#entityName} e where e.playerRating > :rating and e.card.rankingBanned = false") - fun getRanking(rating: Int): Long @Query("select e from #{#entityName} e where e.card.rankingBanned = false") fun findAllNonBanned(): List