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