using System.Collections.Concurrent;
using System.Text;
using System.Text.RegularExpressions;
namespace MxGateway.Server.Galaxy;
public static class GalaxyGlobMatcher
{
///
/// Compiled-regex cache keyed by glob pattern. IsMatch is called once per
/// object per DiscoverHierarchy/WatchDeployEvents evaluation, so the
/// same handful of glob patterns are translated repeatedly; caching avoids
/// rebuilding and recompiling the regex on every call.
///
private static readonly ConcurrentDictionary RegexCache = new(StringComparer.Ordinal);
public static bool IsMatch(string value, string glob)
{
if (string.IsNullOrWhiteSpace(glob))
{
return true;
}
return GetOrCreateRegex(glob).IsMatch(value ?? string.Empty);
}
private static Regex GetOrCreateRegex(string glob)
{
return RegexCache.GetOrAdd(glob, static pattern => new Regex(
BuildRegex(pattern),
RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Compiled,
TimeSpan.FromMilliseconds(100)));
}
private static string BuildRegex(string glob)
{
StringBuilder builder = new("^", glob.Length + 2);
foreach (char character in glob)
{
switch (character)
{
case '*':
builder.Append(".*");
break;
case '?':
builder.Append('.');
break;
default:
builder.Append(Regex.Escape(character.ToString()));
break;
}
}
builder.Append('$');
return builder.ToString();
}
}