From 2c5ba1d8e2d444795c8f1a986a2a039d18d4c8f6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Oct 2021 15:35:51 +0900 Subject: [PATCH] Change `OnlineID` to non-nullable to allow for indexing in Realm --- osu.Game/Beatmaps/BeatmapInfo.cs | 2 +- osu.Game/Beatmaps/BeatmapSetInfo.cs | 2 +- osu.Game/Database/IHasOnlineID.cs | 4 +-- osu.Game/Database/RealmContextFactory.cs | 34 +++++++++++++++++++++++- osu.Game/Models/RealmBeatmap.cs | 3 ++- osu.Game/Models/RealmBeatmapSet.cs | 5 ++-- osu.Game/Models/RealmRuleset.cs | 7 ++--- osu.Game/Rulesets/RulesetInfo.cs | 2 +- 8 files changed, 47 insertions(+), 12 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index ac5b5d7a8a..3bcc00f5de 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -178,7 +178,7 @@ namespace osu.Game.Beatmaps #region Implementation of IHasOnlineID - public int? OnlineID => OnlineBeatmapID; + public int OnlineID => OnlineBeatmapID ?? -1; #endregion diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index 8b01831b3c..e8c77e792f 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -91,7 +91,7 @@ namespace osu.Game.Beatmaps #region Implementation of IHasOnlineID - public int? OnlineID => OnlineBeatmapSetID; + public int OnlineID => OnlineBeatmapSetID ?? -1; #endregion diff --git a/osu.Game/Database/IHasOnlineID.cs b/osu.Game/Database/IHasOnlineID.cs index c55c461d2d..529c68a8f8 100644 --- a/osu.Game/Database/IHasOnlineID.cs +++ b/osu.Game/Database/IHasOnlineID.cs @@ -8,8 +8,8 @@ namespace osu.Game.Database public interface IHasOnlineID { /// - /// The server-side ID representing this instance, if one exists. + /// The server-side ID representing this instance, if one exists. -1 denotes a missing ID. /// - int? OnlineID { get; } + int OnlineID { get; } } } diff --git a/osu.Game/Database/RealmContextFactory.cs b/osu.Game/Database/RealmContextFactory.cs index 82d51e365e..7403550b1e 100644 --- a/osu.Game/Database/RealmContextFactory.cs +++ b/osu.Game/Database/RealmContextFactory.cs @@ -2,12 +2,14 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using System.Threading; using osu.Framework.Allocation; using osu.Framework.Development; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Framework.Statistics; +using osu.Game.Models; using Realms; #nullable enable @@ -26,7 +28,12 @@ namespace osu.Game.Database /// public readonly string Filename; - private const int schema_version = 6; + /// + /// Version history: + /// 6 First tracked version (~20211018) + /// 7 Changed OnlineID fields to non-nullable to add indexing support (20211018) + /// + private const int schema_version = 7; /// /// Lock object which is held during sections, blocking context creation during blocking periods. @@ -120,6 +127,31 @@ namespace osu.Game.Database private void onMigration(Migration migration, ulong lastSchemaVersion) { + if (lastSchemaVersion < 7) + { + convertOnlineIDs(); + convertOnlineIDs(); + convertOnlineIDs(); + + void convertOnlineIDs() where T : RealmObject + { + var className = typeof(T).Name.Replace(@"Realm", string.Empty); + + var oldItems = migration.OldRealm.DynamicApi.All(className); + var newItems = migration.NewRealm.DynamicApi.All(className); + + int itemCount = newItems.Count(); + + for (int i = 0; i < itemCount; i++) + { + var oldItem = oldItems.ElementAt(i); + var newItem = newItems.ElementAt(i); + + long? nullableOnlineID = oldItem.OnlineID; + newItem.OnlineID = (int)(nullableOnlineID ?? -1); + } + } + } } /// diff --git a/osu.Game/Models/RealmBeatmap.cs b/osu.Game/Models/RealmBeatmap.cs index 5049c1384d..9311425cb7 100644 --- a/osu.Game/Models/RealmBeatmap.cs +++ b/osu.Game/Models/RealmBeatmap.cs @@ -44,7 +44,8 @@ namespace osu.Game.Models [MapTo(nameof(Status))] public int StatusInt { get; set; } - public int? OnlineID { get; set; } + [Indexed] + public int OnlineID { get; set; } = -1; public double Length { get; set; } diff --git a/osu.Game/Models/RealmBeatmapSet.cs b/osu.Game/Models/RealmBeatmapSet.cs index 314ca4494b..d6e56fd61c 100644 --- a/osu.Game/Models/RealmBeatmapSet.cs +++ b/osu.Game/Models/RealmBeatmapSet.cs @@ -20,7 +20,8 @@ namespace osu.Game.Models [PrimaryKey] public Guid ID { get; set; } = Guid.NewGuid(); - public int? OnlineID { get; set; } + [Indexed] + public int OnlineID { get; set; } = -1; public DateTimeOffset DateAdded { get; set; } @@ -62,7 +63,7 @@ namespace osu.Game.Models if (IsManaged && other.IsManaged) return ID == other.ID; - if (OnlineID.HasValue && other.OnlineID.HasValue) + if (OnlineID >= 0 && other.OnlineID >= 0) return OnlineID == other.OnlineID; if (!string.IsNullOrEmpty(Hash) && !string.IsNullOrEmpty(other.Hash)) diff --git a/osu.Game/Models/RealmRuleset.cs b/osu.Game/Models/RealmRuleset.cs index 0dcd701ed2..5d70324713 100644 --- a/osu.Game/Models/RealmRuleset.cs +++ b/osu.Game/Models/RealmRuleset.cs @@ -18,7 +18,8 @@ namespace osu.Game.Models [PrimaryKey] public string ShortName { get; set; } = string.Empty; - public int? OnlineID { get; set; } + [Indexed] + public int OnlineID { get; set; } = -1; public string Name { get; set; } = string.Empty; @@ -29,7 +30,7 @@ namespace osu.Game.Models ShortName = shortName; Name = name; InstantiationInfo = instantiationInfo; - OnlineID = onlineID; + OnlineID = onlineID ?? -1; } [UsedImplicitly] @@ -39,7 +40,7 @@ namespace osu.Game.Models public RealmRuleset(int? onlineID, string name, string shortName, bool available) { - OnlineID = onlineID; + OnlineID = onlineID ?? -1; Name = name; ShortName = shortName; Available = available; diff --git a/osu.Game/Rulesets/RulesetInfo.cs b/osu.Game/Rulesets/RulesetInfo.cs index ca6a083a58..8cd3fa8c63 100644 --- a/osu.Game/Rulesets/RulesetInfo.cs +++ b/osu.Game/Rulesets/RulesetInfo.cs @@ -57,7 +57,7 @@ namespace osu.Game.Rulesets #region Implementation of IHasOnlineID - public int? OnlineID => ID; + public int OnlineID => ID ?? -1; #endregion }