Merge pull request #7064 from peppy/eager-skip-filters

Optimise song select filter application to avoid unnecessary property retrieval
This commit is contained in:
Dan Balasescu
2019-12-05 12:43:32 +09:00
committed by GitHub
2 changed files with 22 additions and 16 deletions

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Screens.Select.Filter; using osu.Game.Screens.Select.Filter;
@ -29,28 +30,29 @@ namespace osu.Game.Screens.Select.Carousel
Beatmap.RulesetID == criteria.Ruleset.ID || Beatmap.RulesetID == criteria.Ruleset.ID ||
(Beatmap.RulesetID == 0 && criteria.Ruleset.ID > 0 && criteria.AllowConvertedBeatmaps); (Beatmap.RulesetID == 0 && criteria.Ruleset.ID > 0 && criteria.AllowConvertedBeatmaps);
match &= criteria.StarDifficulty.IsInRange(Beatmap.StarDifficulty); match &= !criteria.StarDifficulty.HasFilter || criteria.StarDifficulty.IsInRange(Beatmap.StarDifficulty);
match &= criteria.ApproachRate.IsInRange(Beatmap.BaseDifficulty.ApproachRate); match &= !criteria.ApproachRate.HasFilter || criteria.ApproachRate.IsInRange(Beatmap.BaseDifficulty.ApproachRate);
match &= criteria.DrainRate.IsInRange(Beatmap.BaseDifficulty.DrainRate); match &= !criteria.DrainRate.HasFilter || criteria.DrainRate.IsInRange(Beatmap.BaseDifficulty.DrainRate);
match &= criteria.CircleSize.IsInRange(Beatmap.BaseDifficulty.CircleSize); match &= !criteria.CircleSize.HasFilter || criteria.CircleSize.IsInRange(Beatmap.BaseDifficulty.CircleSize);
match &= criteria.Length.IsInRange(Beatmap.Length); match &= !criteria.Length.HasFilter || criteria.Length.IsInRange(Beatmap.Length);
match &= criteria.BPM.IsInRange(Beatmap.BPM); match &= !criteria.BPM.HasFilter || criteria.BPM.IsInRange(Beatmap.BPM);
match &= criteria.BeatDivisor.IsInRange(Beatmap.BeatDivisor); match &= !criteria.BeatDivisor.HasFilter || criteria.BeatDivisor.IsInRange(Beatmap.BeatDivisor);
match &= criteria.OnlineStatus.IsInRange(Beatmap.Status); match &= !criteria.OnlineStatus.HasFilter || criteria.OnlineStatus.IsInRange(Beatmap.Status);
match &= criteria.Creator.Matches(Beatmap.Metadata.AuthorString); match &= !criteria.Creator.HasFilter || criteria.Creator.Matches(Beatmap.Metadata.AuthorString);
match &= criteria.Artist.Matches(Beatmap.Metadata.Artist) || match &= !criteria.Artist.HasFilter || criteria.Artist.Matches(Beatmap.Metadata.Artist) ||
criteria.Artist.Matches(Beatmap.Metadata.ArtistUnicode); criteria.Artist.Matches(Beatmap.Metadata.ArtistUnicode);
if (match) if (match)
{ {
var terms = new List<string>();
terms.AddRange(Beatmap.Metadata.SearchableTerms);
terms.Add(Beatmap.Version);
foreach (var criteriaTerm in criteria.SearchTerms) foreach (var criteriaTerm in criteria.SearchTerms)
{ match &= terms.Any(term => term.IndexOf(criteriaTerm, StringComparison.InvariantCultureIgnoreCase) >= 0);
match &=
Beatmap.Metadata.SearchableTerms.Any(term => term.IndexOf(criteriaTerm, StringComparison.InvariantCultureIgnoreCase) >= 0) ||
Beatmap.Version.IndexOf(criteriaTerm, StringComparison.InvariantCultureIgnoreCase) >= 0;
}
} }
Filtered.Value = !match; Filtered.Value = !match;

View File

@ -46,6 +46,8 @@ namespace osu.Game.Screens.Select
public struct OptionalRange<T> : IEquatable<OptionalRange<T>> public struct OptionalRange<T> : IEquatable<OptionalRange<T>>
where T : struct, IComparable where T : struct, IComparable
{ {
public bool HasFilter => Max != null || Min != null;
public bool IsInRange(T value) public bool IsInRange(T value)
{ {
if (Min != null) if (Min != null)
@ -87,9 +89,11 @@ namespace osu.Game.Screens.Select
public struct OptionalTextFilter : IEquatable<OptionalTextFilter> public struct OptionalTextFilter : IEquatable<OptionalTextFilter>
{ {
public bool HasFilter => !string.IsNullOrEmpty(SearchTerm);
public bool Matches(string value) public bool Matches(string value)
{ {
if (string.IsNullOrEmpty(SearchTerm)) if (!HasFilter)
return true; return true;
// search term is guaranteed to be non-empty, so if the string we're comparing is empty, it's not matching // search term is guaranteed to be non-empty, so if the string we're comparing is empty, it's not matching