From dd09f0af25529baa85ee770e505cf94ffac69504 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Fri, 11 Jun 2021 20:22:25 +0200 Subject: [PATCH] added HasAnyFlag and improved memory performance of HasFlag in DynamicEnum --- MLEM.Data/DynamicEnum.cs | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/MLEM.Data/DynamicEnum.cs b/MLEM.Data/DynamicEnum.cs index 58aa6f4..6fbd7bb 100644 --- a/MLEM.Data/DynamicEnum.cs +++ b/MLEM.Data/DynamicEnum.cs @@ -32,6 +32,9 @@ namespace MLEM.Data { private static readonly Dictionary> ParseCache = new Dictionary>(); private readonly BigInteger value; + + private Dictionary allFlagsCache; + private Dictionary anyFlagsCache; private string name; /// @@ -46,13 +49,38 @@ namespace MLEM.Data { } /// - /// Returns true if this enum value has the given flag on it. + /// Returns true if this enum value has ALL of the given flags on it. /// This operation is equivalent to . /// - /// The flag to query - /// True if the flag is present, false otherwise - public bool HasFlag(DynamicEnum flag) { - return (GetValue(this) & GetValue(flag)) == GetValue(flag); + /// + /// The flags to query + /// True if all of the flags are present, false otherwise + public bool HasFlag(DynamicEnum flags) { + if (this.allFlagsCache == null) + this.allFlagsCache = new Dictionary(); + if (!this.allFlagsCache.TryGetValue(flags, out var ret)) { + // & is very memory-intensive, so we cache the return value + ret = (GetValue(this) & GetValue(flags)) == GetValue(flags); + this.allFlagsCache.Add(flags, ret); + } + return ret; + } + + /// + /// Returns true if this enum value has ANY of the given flags on it + /// + /// + /// The flags to query + /// True if one of the flags is present, false otherwise + public bool HasAnyFlag(DynamicEnum flags) { + if (this.anyFlagsCache == null) + this.anyFlagsCache = new Dictionary(); + if (!this.anyFlagsCache.TryGetValue(flags, out var ret)) { + // & is very memory-intensive, so we cache the return value + ret = (GetValue(this) & GetValue(flags)) != 0; + this.anyFlagsCache.Add(flags, ret); + } + return ret; } ///