From 81f82c24c39014decc49b676e68cca913db95645 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 1 Dec 2021 17:45:41 +0900 Subject: [PATCH] Use new API endpoint to do batch lookups --- osu.Game/Database/BeatmapLookupCache.cs | 19 ++++++++------- .../Online/API/Requests/GetBeatmapsRequest.cs | 24 +++++++++++++++++++ .../API/Requests/GetBeatmapsResponse.cs | 15 ++++++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 osu.Game/Online/API/Requests/GetBeatmapsRequest.cs create mode 100644 osu.Game/Online/API/Requests/GetBeatmapsResponse.cs diff --git a/osu.Game/Database/BeatmapLookupCache.cs b/osu.Game/Database/BeatmapLookupCache.cs index c4e20d59b6..2082031714 100644 --- a/osu.Game/Database/BeatmapLookupCache.cs +++ b/osu.Game/Database/BeatmapLookupCache.cs @@ -85,7 +85,7 @@ namespace osu.Game.Database // Grab at most 50 unique beatmap IDs from the queue. lock (taskAssignmentLock) { - while (pendingBeatmapTasks.Count > 0 && beatmapTasks.Count < 1) + while (pendingBeatmapTasks.Count > 0 && beatmapTasks.Count < 50) { (int id, TaskCompletionSource task) next = pendingBeatmapTasks.Dequeue(); @@ -103,7 +103,7 @@ namespace osu.Game.Database } // Query the beatmaps. - var request = new GetBeatmapRequest(new APIBeatmap { OnlineID = beatmapTasks.Keys.First() }); + var request = new GetBeatmapsRequest(beatmapTasks.Keys.ToArray()); // rather than queueing, we maintain our own single-threaded request stream. // todo: we probably want retry logic here. @@ -117,16 +117,19 @@ namespace osu.Game.Database createNewTask(); } - List foundBeatmaps = new List { request.Response }; + List foundBeatmaps = request.Response?.Beatmaps; - foreach (var beatmap in foundBeatmaps) + if (foundBeatmaps != null) { - if (beatmapTasks.TryGetValue(beatmap.OnlineID, out var tasks)) + foreach (var beatmap in foundBeatmaps) { - foreach (var task in tasks) - task.SetResult(beatmap); + if (beatmapTasks.TryGetValue(beatmap.OnlineID, out var tasks)) + { + foreach (var task in tasks) + task.SetResult(beatmap); - beatmapTasks.Remove(beatmap.OnlineID); + beatmapTasks.Remove(beatmap.OnlineID); + } } } diff --git a/osu.Game/Online/API/Requests/GetBeatmapsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapsRequest.cs new file mode 100644 index 0000000000..1d71e22b77 --- /dev/null +++ b/osu.Game/Online/API/Requests/GetBeatmapsRequest.cs @@ -0,0 +1,24 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; + +namespace osu.Game.Online.API.Requests +{ + public class GetBeatmapsRequest : APIRequest + { + private readonly int[] beatmapIds; + + private const int max_ids_per_request = 50; + + public GetBeatmapsRequest(int[] beatmapIds) + { + if (beatmapIds.Length > max_ids_per_request) + throw new ArgumentException($"{nameof(GetBeatmapsRequest)} calls only support up to {max_ids_per_request} IDs at once"); + + this.beatmapIds = beatmapIds; + } + + protected override string Target => "beatmaps/?ids[]=" + string.Join("&ids[]=", beatmapIds); + } +} diff --git a/osu.Game/Online/API/Requests/GetBeatmapsResponse.cs b/osu.Game/Online/API/Requests/GetBeatmapsResponse.cs new file mode 100644 index 0000000000..c450c3269c --- /dev/null +++ b/osu.Game/Online/API/Requests/GetBeatmapsResponse.cs @@ -0,0 +1,15 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using Newtonsoft.Json; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class GetBeatmapsResponse : ResponseWithCursor + { + [JsonProperty("beatmaps")] + public List Beatmaps; + } +}