From 60b80c88b60b356abc0ab3e27ef9b09817b34b30 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Jan 2022 00:49:16 +0900 Subject: [PATCH] Avoid file retrieval overhead when detaching `BeatmapSetInfo` It seems that no usages of `BeatmapSetInfo` detaches require files - a `WorkingBeatmap` is always obtained before doing further lookups. Therefore we can omit this include unless the detaching object is a `BeatmapInfo`. A refetch is performed when retrieving a `WorkingBeatmap` to complete the equation. --- osu.Game/Beatmaps/BeatmapManager.cs | 18 +++++++++++++++- osu.Game/Database/RealmObjectExtensions.cs | 24 +++++++++++++++------- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index f901b0fbc1..d983c087a0 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -299,7 +299,23 @@ namespace osu.Game.Beatmaps #region Implementation of IWorkingBeatmapCache - public WorkingBeatmap GetWorkingBeatmap(BeatmapInfo? importedBeatmap) => workingBeatmapCache.GetWorkingBeatmap(importedBeatmap); + public WorkingBeatmap GetWorkingBeatmap(BeatmapInfo? importedBeatmap) + { + // Detached sets don't come with files. + // If we seem to be missing files, now is a good time to re-fetch. + if (importedBeatmap?.BeatmapSet?.Files.Count == 0) + { + using (var realm = contextFactory.CreateContext()) + { + var refetch = realm.Find(importedBeatmap.ID)?.Detach(); + + if (refetch != null) + importedBeatmap = refetch; + } + } + + return workingBeatmapCache.GetWorkingBeatmap(importedBeatmap); + } public WorkingBeatmap GetWorkingBeatmap(ILive? importedBeatmap) { diff --git a/osu.Game/Database/RealmObjectExtensions.cs b/osu.Game/Database/RealmObjectExtensions.cs index 5ab7154486..140f41c5d8 100644 --- a/osu.Game/Database/RealmObjectExtensions.cs +++ b/osu.Game/Database/RealmObjectExtensions.cs @@ -76,6 +76,14 @@ namespace osu.Game.Database { applyCommonConfiguration(c); + c.CreateMap() + .MaxDepth(2) + .AfterMap((s, d) => + { + foreach (var beatmap in d.Beatmaps) + beatmap.BeatmapSet = d; + }); + // This can be further optimised to reduce cyclic retrievals, similar to the optimised set mapper below. // Only hasn't been done yet as we detach at the point of BeatmapInfo less often. c.CreateMap() @@ -100,6 +108,15 @@ namespace osu.Game.Database { applyCommonConfiguration(c); + c.CreateMap() + .MaxDepth(2) + .ForMember(b => b.Files, cc => cc.Ignore()) + .AfterMap((s, d) => + { + foreach (var beatmap in d.Beatmaps) + beatmap.BeatmapSet = d; + }); + c.CreateMap() .MaxDepth(1) .ForMember(b => b.BeatmapSet, cc => cc.Ignore()); @@ -131,13 +148,6 @@ namespace osu.Game.Database c.CreateMap(); c.CreateMap(); c.CreateMap(); - c.CreateMap() - .MaxDepth(2) - .AfterMap((s, d) => - { - foreach (var beatmap in d.Beatmaps) - beatmap.BeatmapSet = d; - }); } ///