1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 09:27:34 +08:00

Optimise filters to avoid property retrieval

Also reduces number of instantiations of SearchableTerms array in the case of multiple criteria terms.
This commit is contained in:
Dean Herbert 2019-12-05 01:52:22 +09:00
parent bb00b4166e
commit 48287459a0
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.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Screens.Select.Filter;
@ -29,28 +30,29 @@ namespace osu.Game.Screens.Select.Carousel
Beatmap.RulesetID == criteria.Ruleset.ID ||
(Beatmap.RulesetID == 0 && criteria.Ruleset.ID > 0 && criteria.AllowConvertedBeatmaps);
match &= criteria.StarDifficulty.IsInRange(Beatmap.StarDifficulty);
match &= criteria.ApproachRate.IsInRange(Beatmap.BaseDifficulty.ApproachRate);
match &= criteria.DrainRate.IsInRange(Beatmap.BaseDifficulty.DrainRate);
match &= criteria.CircleSize.IsInRange(Beatmap.BaseDifficulty.CircleSize);
match &= criteria.Length.IsInRange(Beatmap.Length);
match &= criteria.BPM.IsInRange(Beatmap.BPM);
match &= !criteria.StarDifficulty.HasFilter || criteria.StarDifficulty.IsInRange(Beatmap.StarDifficulty);
match &= !criteria.ApproachRate.HasFilter || criteria.ApproachRate.IsInRange(Beatmap.BaseDifficulty.ApproachRate);
match &= !criteria.DrainRate.HasFilter || criteria.DrainRate.IsInRange(Beatmap.BaseDifficulty.DrainRate);
match &= !criteria.CircleSize.HasFilter || criteria.CircleSize.IsInRange(Beatmap.BaseDifficulty.CircleSize);
match &= !criteria.Length.HasFilter || criteria.Length.IsInRange(Beatmap.Length);
match &= !criteria.BPM.HasFilter || criteria.BPM.IsInRange(Beatmap.BPM);
match &= criteria.BeatDivisor.IsInRange(Beatmap.BeatDivisor);
match &= criteria.OnlineStatus.IsInRange(Beatmap.Status);
match &= !criteria.BeatDivisor.HasFilter || criteria.BeatDivisor.IsInRange(Beatmap.BeatDivisor);
match &= !criteria.OnlineStatus.HasFilter || criteria.OnlineStatus.IsInRange(Beatmap.Status);
match &= criteria.Creator.Matches(Beatmap.Metadata.AuthorString);
match &= criteria.Artist.Matches(Beatmap.Metadata.Artist) ||
match &= !criteria.Creator.HasFilter || criteria.Creator.Matches(Beatmap.Metadata.AuthorString);
match &= !criteria.Artist.HasFilter || criteria.Artist.Matches(Beatmap.Metadata.Artist) ||
criteria.Artist.Matches(Beatmap.Metadata.ArtistUnicode);
if (match)
{
var terms = new List<string>();
terms.AddRange(Beatmap.Metadata.SearchableTerms);
terms.Add(Beatmap.Version);
foreach (var criteriaTerm in criteria.SearchTerms)
{
match &=
Beatmap.Metadata.SearchableTerms.Any(term => term.IndexOf(criteriaTerm, StringComparison.InvariantCultureIgnoreCase) >= 0) ||
Beatmap.Version.IndexOf(criteriaTerm, StringComparison.InvariantCultureIgnoreCase) >= 0;
}
match &= terms.Any(term => term.IndexOf(criteriaTerm, StringComparison.InvariantCultureIgnoreCase) >= 0);
}
Filtered.Value = !match;

View File

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