From 9637784f506858fead042f51ebe09f665b96dc86 Mon Sep 17 00:00:00 2001 From: Apollo3zehn Date: Fri, 26 Jul 2024 23:27:25 +0200 Subject: [PATCH 1/4] Use regex properties instead of methods --- src/Nexus.UI/Core/Utilities.cs | 7 +++---- src/Nexus/PackageManagement/PackageController.cs | 10 +++++----- src/Nexus/Utilities/NexusUtilities.cs | 8 ++++---- .../DataModel/DataModelExtensions.cs | 7 +++---- .../DataModel/DataModelUtilities.cs | 7 +++---- .../dotnet-extensibility/DataModel/Representation.cs | 7 +++---- .../dotnet-extensibility/DataModel/Resource.cs | 6 ++---- .../dotnet-extensibility/DataModel/ResourceCatalog.cs | 6 ++---- 8 files changed, 25 insertions(+), 33 deletions(-) diff --git a/src/Nexus.UI/Core/Utilities.cs b/src/Nexus.UI/Core/Utilities.cs index 4309c4c6..9916323a 100644 --- a/src/Nexus.UI/Core/Utilities.cs +++ b/src/Nexus.UI/Core/Utilities.cs @@ -32,8 +32,10 @@ public static string EscapeDataString(string catalogId) private static readonly long[] _nanoseconds = [(long)1e0, (long)1e3, (long)1e6, (long)1e9, (long)60e9, (long)3600e9, (long)86400e9]; private static readonly int[] _quotients = [1000, 1000, 1000, 60, 60, 24, 1]; private static readonly string[] _postFixes = ["ns", "us", "ms", "s", "min", "h", "d"]; + // ... except this line - private static readonly Regex _unitStringEvaluator = UnitStringEvaluator(); + [GeneratedRegex(@"^\s*([0-9]+)[\s_]*([a-zA-Z]+)\s*$")] + private static partial Regex _unitStringEvaluator { get; } public static string ToUnitString(this TimeSpan samplePeriod, bool withUnderScore = false) { @@ -334,7 +336,4 @@ private static JsonElement GetJsonObjectFromPath(this JsonElement root, Span DiscoverGithubReleasesAsync(CancellationToken cance .First() .Split(",") .Where(current => current.Contains("rel=\"next\"")) - .Select(current => GitHubRegex().Match(current).Groups[1].Value) + .Select(current => GitHubRegex.Match(current).Groups[1].Value) .FirstOrDefault(); if (requestUrl == default) @@ -497,7 +497,7 @@ private async Task DiscoverGithubReleasesAsync(CancellationToken cance continue; } - return [.. result]; + return result.ToArray(); } private async Task RestoreGitHubReleasesAsync(string restoreRoot, CancellationToken cancellationToken) @@ -749,7 +749,7 @@ private static async IAsyncEnumerable GetGitLabPackagesGenericAsync .First() .Split(",") .Where(current => current.Contains("rel=\"next\"")) - .Select(current => GitlabRegex().Match(current).Groups[1].Value) + .Select(current => GitlabRegex.Match(current).Groups[1].Value) .FirstOrDefault(); if (requestUrl == default) @@ -760,10 +760,10 @@ private static async IAsyncEnumerable GetGitLabPackagesGenericAsync } [GeneratedRegex("\\<(https:.*)\\>; rel=\"next\"")] - private static partial Regex GitHubRegex(); + private static partial Regex GitHubRegex { get; } [GeneratedRegex("\\<(https:.*)\\>; rel=\"next\"")] - private static partial Regex GitlabRegex(); + private static partial Regex GitlabRegex { get; } #endregion diff --git a/src/Nexus/Utilities/NexusUtilities.cs b/src/Nexus/Utilities/NexusUtilities.cs index e32a4819..38dfa59c 100644 --- a/src/Nexus/Utilities/NexusUtilities.cs +++ b/src/Nexus/Utilities/NexusUtilities.cs @@ -24,7 +24,7 @@ public static string DefaultBaseUrl if (aspnetcoreEnvVar is not null) { - var match = AspNetCoreEnvVarRegex().Match(aspnetcoreEnvVar); + var match = AspNetCoreEnvVarRegex.Match(aspnetcoreEnvVar); if (match.Success && int.TryParse(match.Groups[1].Value, out var parsedPort)) port = parsedPort; @@ -37,6 +37,9 @@ public static string DefaultBaseUrl } } + [GeneratedRegex(":([0-9]+)")] + private static partial Regex AspNetCoreEnvVarRegex { get; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Scale(TimeSpan value, TimeSpan samplePeriod) => (int)(value.Ticks / samplePeriod.Ticks); @@ -151,7 +154,4 @@ public static IEnumerable GetCustomAttributes(this Type type) where T : At { return type.GetCustomAttributes(false).OfType(); } - - [GeneratedRegex(":([0-9]+)")] - private static partial Regex AspNetCoreEnvVarRegex(); } \ No newline at end of file diff --git a/src/extensibility/dotnet-extensibility/DataModel/DataModelExtensions.cs b/src/extensibility/dotnet-extensibility/DataModel/DataModelExtensions.cs index afc13b9f..27ae719c 100644 --- a/src/extensibility/dotnet-extensibility/DataModel/DataModelExtensions.cs +++ b/src/extensibility/dotnet-extensibility/DataModel/DataModelExtensions.cs @@ -163,7 +163,9 @@ public static string ToPath(this Uri url) private static readonly string[] _postFixes = ["ns", "us", "ms", "s", "min", "h", "d"]; // ... except these lines - private static readonly Regex _unitStringEvaluator = UnitStringEvaluator(); + + [GeneratedRegex(@"^([0-9]+)_([a-z]+)$")] + private static partial Regex _unitStringEvaluator { get; } internal const string NEXUS_KEY = "nexus"; @@ -215,9 +217,6 @@ internal static TimeSpan ToSamplePeriod(string unitString) return new TimeSpan(ticks); } - [GeneratedRegex(@"^([0-9]+)_([a-z]+)$", RegexOptions.Compiled)] - private static partial Regex UnitStringEvaluator(); - internal static ResourceCatalog EnsureAndSanitizeMandatoryProperties( this ResourceCatalog catalog, int pipelinePosition, diff --git a/src/extensibility/dotnet-extensibility/DataModel/DataModelUtilities.cs b/src/extensibility/dotnet-extensibility/DataModel/DataModelUtilities.cs index a6f90b41..1e2b3332 100644 --- a/src/extensibility/dotnet-extensibility/DataModel/DataModelUtilities.cs +++ b/src/extensibility/dotnet-extensibility/DataModel/DataModelUtilities.cs @@ -21,7 +21,9 @@ internal static partial class DataModelUtilities * /a/b/c/T1/600_s_mean(abc=456)#base=1s */ // keep in sync with Nexus.UI.Core.Utilities - private static readonly Regex _resourcePathEvaluator = ResourcePathEvaluator(); + + [GeneratedRegex(@"^(?'catalog'.*)\/(?'resource'.*)\/(?'sample_period'[0-9]+_[a-zA-Z]+)(?:_(?'kind'[^\(#\s]+))?(?:\((?'parameters'.*)\))?(?:#(?'fragment'.*))?$")] + private static partial Regex _resourcePathEvaluator { get; } private static string ToPascalCase(string input) { @@ -288,7 +290,4 @@ private static void MergeArrays(JsonArray currentArray, JsonElement root1, JsonE _ => JsonValue.Create(element) }; } - - [GeneratedRegex(@"^(?'catalog'.*)\/(?'resource'.*)\/(?'sample_period'[0-9]+_[a-zA-Z]+)(?:_(?'kind'[^\(#\s]+))?(?:\((?'parameters'.*)\))?(?:#(?'fragment'.*))?$", RegexOptions.Compiled)] - private static partial Regex ResourcePathEvaluator(); } \ No newline at end of file diff --git a/src/extensibility/dotnet-extensibility/DataModel/Representation.cs b/src/extensibility/dotnet-extensibility/DataModel/Representation.cs index e2036794..3bda4cf6 100644 --- a/src/extensibility/dotnet-extensibility/DataModel/Representation.cs +++ b/src/extensibility/dotnet-extensibility/DataModel/Representation.cs @@ -14,7 +14,9 @@ namespace Nexus.DataModel; [DebuggerDisplay("{Id,nq}")] public partial record Representation { - private static readonly Regex _snakeCaseEvaluator = SnakeCaseEvaluator(); + [GeneratedRegex("(?<=[a-z])([A-Z])")] + private static partial Regex _snakeCaseEvaluator { get; } + private static readonly HashSet _nexusDataTypeValues = new(Enum.GetValues()); private IReadOnlyDictionary? _parameters; @@ -139,7 +141,4 @@ private static void ValidateParameters(IReadOnlyDictionary throw new Exception("The representation argument identifier is not valid."); } } - - [GeneratedRegex("(?<=[a-z])([A-Z])", RegexOptions.Compiled)] - private static partial Regex SnakeCaseEvaluator(); } \ No newline at end of file diff --git a/src/extensibility/dotnet-extensibility/DataModel/Resource.cs b/src/extensibility/dotnet-extensibility/DataModel/Resource.cs index 2315e10c..54e75b15 100644 --- a/src/extensibility/dotnet-extensibility/DataModel/Resource.cs +++ b/src/extensibility/dotnet-extensibility/DataModel/Resource.cs @@ -37,7 +37,8 @@ public Resource( /// /// Gets a regular expression to validate a resource identifier. /// - public static Regex ValidIdExpression { get; } = ValidExpression(); + [GeneratedRegex(@"^[a-zA-Z_][a-zA-Z_0-9]*$")] + public static partial Regex ValidIdExpression { get; } /// /// Gets a regular expression to find invalid characters in a resource identifier. @@ -126,7 +127,4 @@ private static void ValidateRepresentations(IReadOnlyList repres if (uniqueIds.Count() != representations.Count) throw new ArgumentException("There are multiple representations with the same identifier."); } - - [GeneratedRegex(@"^[a-zA-Z_][a-zA-Z_0-9]*$")] - private static partial Regex ValidExpression(); } \ No newline at end of file diff --git a/src/extensibility/dotnet-extensibility/DataModel/ResourceCatalog.cs b/src/extensibility/dotnet-extensibility/DataModel/ResourceCatalog.cs index d0e97f60..6f678953 100644 --- a/src/extensibility/dotnet-extensibility/DataModel/ResourceCatalog.cs +++ b/src/extensibility/dotnet-extensibility/DataModel/ResourceCatalog.cs @@ -39,7 +39,8 @@ public ResourceCatalog( /// /// Gets a regular expression to validate a resource catalog identifier. /// - public static Regex ValidIdExpression { get; } = ValidIdExpressionRegex(); + [GeneratedRegex(@"^(?:\/[a-zA-Z_][a-zA-Z_0-9]*)+$")] + public static partial Regex ValidIdExpression { get; } private static Regex _matchSingleParametersExpression { get; } = new Regex(@"\s*(.+?)\s*=\s*([^,\)]+)\s*,?", RegexOptions.Compiled); @@ -203,7 +204,4 @@ private static void ValidateResources(IReadOnlyList resources) if (uniqueIds.Count() != resources.Count) throw new ArgumentException("There are multiple resources with the same identifier."); } - - [GeneratedRegex(@"^(?:\/[a-zA-Z_][a-zA-Z_0-9]*)+$", RegexOptions.Compiled)] - private static partial Regex ValidIdExpressionRegex(); } From e3f824eb4b953fc5fd5133b1043d5ac3f7d21ec3 Mon Sep 17 00:00:00 2001 From: Apollo3zehn Date: Thu, 8 Aug 2024 12:21:39 +0200 Subject: [PATCH 2/4] Remove useless continue statement --- src/Nexus/PackageManagement/PackageController.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Nexus/PackageManagement/PackageController.cs b/src/Nexus/PackageManagement/PackageController.cs index 1e4da1f0..66d55892 100644 --- a/src/Nexus/PackageManagement/PackageController.cs +++ b/src/Nexus/PackageManagement/PackageController.cs @@ -493,8 +493,6 @@ private async Task DiscoverGithubReleasesAsync(CancellationToken cance if (requestUrl == default) break; - - continue; } return result.ToArray(); From 21e69d93f20bbcaba8891f4dba66004cd0ec9c00 Mon Sep 17 00:00:00 2001 From: Apollo3zehn <20972129+Apollo3zehn@users.noreply.github.com> Date: Thu, 8 Aug 2024 13:25:42 +0200 Subject: [PATCH 3/4] [Add] Use stackalloc in combination with the new params collection improvements (#138) * Reduce number of array allocations * Use C# params collections + collection expression feature --------- Co-authored-by: Apollo3zehn --- src/Nexus/API/CatalogsController.cs | 2 +- .../DataSource/DataSourceController.cs | 7 +++++-- src/Nexus/Extensions/Sources/Sample.cs | 4 ++-- src/Nexus/Extensions/Writers/Csv.cs | 10 ++++------ src/Nexus/Services/AppStateManager.cs | 2 +- .../DataModel/DataModelExtensions.cs | 15 ++++++++------- .../DataModel/PropertiesExtensions.cs | 16 +++++++--------- .../DataModel/ResourceCatalog.cs | 6 ++---- .../Extensibility/DataSource/DataSourceTypes.cs | 2 +- .../DataSource/SampleDataSourceTests.cs | 4 ++-- 10 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/Nexus/API/CatalogsController.cs b/src/Nexus/API/CatalogsController.cs index 9046611c..69574cd8 100644 --- a/src/Nexus/API/CatalogsController.cs +++ b/src/Nexus/API/CatalogsController.cs @@ -298,7 +298,7 @@ public async Task> if (license is null) { var catalogInfo = await catalogContainer.GetLazyCatalogInfoAsync(cancellationToken); - license = catalogInfo.Catalog.Properties?.GetStringValue([DataModelExtensions.LicenseKey]); + license = catalogInfo.Catalog.Properties?.GetStringValue(DataModelExtensions.LicenseKey); } return license; diff --git a/src/Nexus/Extensibility/DataSource/DataSourceController.cs b/src/Nexus/Extensibility/DataSource/DataSourceController.cs index 6481ebdf..fd94e370 100644 --- a/src/Nexus/Extensibility/DataSource/DataSourceController.cs +++ b/src/Nexus/Extensibility/DataSource/DataSourceController.cs @@ -59,7 +59,6 @@ internal class DataSourceController( DataOptions dataOptions, ILogger logger) : IDataSourceController { - private static readonly string[] _pipelinePositionPath = [DataModelExtensions.NEXUS_KEY, DataModelExtensions.PIPELINE_POSITION_KEY]; internal readonly IReadOnlyDictionary? _requestConfiguration = requestConfiguration; @@ -422,7 +421,11 @@ private async Task ReadOriginalAsync( var currentReadRequests = readRequests .Where(request => request.CatalogItem.Resource.Properties is null || - request.CatalogItem.Resource.Properties.GetIntValue(_pipelinePositionPath) == pipelinePosition + request.CatalogItem.Resource.Properties + .GetIntValue( + DataModelExtensions.NEXUS_KEY, + DataModelExtensions.PIPELINE_POSITION_KEY + ) == pipelinePosition ) .ToArray(); diff --git a/src/Nexus/Extensions/Sources/Sample.cs b/src/Nexus/Extensions/Sources/Sample.cs index 105c506c..7a4cc826 100644 --- a/src/Nexus/Extensions/Sources/Sample.cs +++ b/src/Nexus/Extensions/Sources/Sample.cs @@ -158,8 +158,8 @@ public async Task ReadAsync( // check credentials if (catalog.Id == RemoteCatalogId) { - var user = Context.RequestConfiguration?.GetStringValue([typeof(Sample).FullName!, "user"]); - var password = Context.RequestConfiguration?.GetStringValue([typeof(Sample).FullName!, "password"]); + var user = Context.RequestConfiguration?.GetStringValue(typeof(Sample).FullName!, "user"); + var password = Context.RequestConfiguration?.GetStringValue(typeof(Sample).FullName!, "password"); if (user != RemoteUsername || password != RemotePassword) throw new Exception("The provided credentials are invalid."); diff --git a/src/Nexus/Extensions/Writers/Csv.cs b/src/Nexus/Extensions/Writers/Csv.cs index 5b4eba42..0aebaf95 100644 --- a/src/Nexus/Extensions/Writers/Csv.cs +++ b/src/Nexus/Extensions/Writers/Csv.cs @@ -26,8 +26,6 @@ namespace Nexus.Writers; "https://github.com/nexus-main/nexus/blob/master/src/Nexus/Extensions/Writers/Csv.cs")] internal class Csv : IDataWriter, IDisposable { - private static readonly string[] _unitPath = [DataModelExtensions.UnitKey]; - private const string DESCRIPTION = """ { "label":"CSV + Schema (*.csv)", @@ -114,7 +112,7 @@ public async Task OpenAsync( if (!_resourceMap.TryGetValue(resourceFilePath, out var resource)) { - var rowIndexFormat = Context.RequestConfiguration?.GetStringValue(["row-index-format"]) ?? "index"; + var rowIndexFormat = Context.RequestConfiguration?.GetStringValue("row-index-format") ?? "index"; var constraints = new Constraints(Required: true); var timestampField = rowIndexFormat switch @@ -211,9 +209,9 @@ public async Task WriteAsync(TimeSpan fileOffset, WriteRequest[] requests, IProg .GroupBy(request => request.CatalogItem.Catalog.Id) .ToList(); - var rowIndexFormat = Context.RequestConfiguration?.GetStringValue(["row-index-format"]) ?? "index"; + var rowIndexFormat = Context.RequestConfiguration?.GetStringValue("row-index-format") ?? "index"; - var significantFigures = int.Parse(Context.RequestConfiguration?.GetStringValue(["significant-figures"]) ?? "4"); + var significantFigures = int.Parse(Context.RequestConfiguration?.GetStringValue("significant-figures") ?? "4"); significantFigures = Math.Clamp(significantFigures, 0, 30); var groupIndex = 0; @@ -307,7 +305,7 @@ private static void AppendWindowsNewLine(StringBuilder stringBuilder) private static string GetFieldName(CatalogItem catalogItem) { var unit = catalogItem.Resource.Properties? - .GetStringValue(_unitPath); + .GetStringValue(DataModelExtensions.UnitKey); var fieldName = $"{catalogItem.Resource.Id}_{catalogItem.Representation.Id}{DataModelUtilities.GetRepresentationParameterString(catalogItem.Parameters)}"; diff --git a/src/Nexus/Services/AppStateManager.cs b/src/Nexus/Services/AppStateManager.cs index a797a461..8187e70c 100644 --- a/src/Nexus/Services/AppStateManager.cs +++ b/src/Nexus/Services/AppStateManager.cs @@ -162,7 +162,7 @@ private void LoadDataWriters() } var additionalInformation = attribute.Description; - var label = (additionalInformation?.GetStringValue([UI.Core.Constants.DATA_WRITER_LABEL_KEY])) ?? throw new Exception($"The description of data writer {fullName} has no label property"); + var label = (additionalInformation?.GetStringValue(UI.Core.Constants.DATA_WRITER_LABEL_KEY)) ?? throw new Exception($"The description of data writer {fullName} has no label property"); var version = dataWriterType.Assembly .GetCustomAttribute()! .InformationalVersion; diff --git a/src/extensibility/dotnet-extensibility/DataModel/DataModelExtensions.cs b/src/extensibility/dotnet-extensibility/DataModel/DataModelExtensions.cs index 27ae719c..2272f787 100644 --- a/src/extensibility/dotnet-extensibility/DataModel/DataModelExtensions.cs +++ b/src/extensibility/dotnet-extensibility/DataModel/DataModelExtensions.cs @@ -229,18 +229,19 @@ IDataSource[] dataSources var isModified = false; var newResources = new List(); - string[] originalNamePath = [OriginalNameKey]; - string[] pipelinePositionPath = [NEXUS_KEY, PIPELINE_POSITION_KEY]; - string[] groupsPath = [GroupsKey]; - foreach (var resource in catalog.Resources) { var resourceProperties = resource.Properties; var newResource = resource; - var originalName = resourceProperties?.GetStringValue(originalNamePath); - var currentPipelinePosition = resourceProperties?.GetIntValue(pipelinePositionPath); - var groups = resourceProperties?.GetStringArray(groupsPath); + var originalName = resourceProperties? + .GetStringValue(OriginalNameKey); + + var currentPipelinePosition = resourceProperties? + .GetIntValue(NEXUS_KEY, PIPELINE_POSITION_KEY); + + var groups = resourceProperties? + .GetStringArray(GroupsKey); var distinctGroups = groups is null ? default diff --git a/src/extensibility/dotnet-extensibility/DataModel/PropertiesExtensions.cs b/src/extensibility/dotnet-extensibility/DataModel/PropertiesExtensions.cs index 2ef71984..c0576850 100644 --- a/src/extensibility/dotnet-extensibility/DataModel/PropertiesExtensions.cs +++ b/src/extensibility/dotnet-extensibility/DataModel/PropertiesExtensions.cs @@ -17,10 +17,8 @@ public static class PropertiesExtensions /// The properties. /// The propery path segments. /// - public static string? GetStringValue(this IReadOnlyDictionary properties, Span pathSegments) + public static string? GetStringValue(this IReadOnlyDictionary properties, params ReadOnlySpan pathSegments) { - // TODO Maybe use params collection (Span) in future? https://github.com/dotnet/csharplang/issues/7700 - if (properties.TryGetValue(pathSegments[0], out var element)) { pathSegments = pathSegments[1..]; @@ -44,7 +42,7 @@ public static class PropertiesExtensions /// The properties. /// The propery path segments. /// - public static string? GetStringValue(this JsonElement properties, Span pathSegments) + public static string? GetStringValue(this JsonElement properties, params ReadOnlySpan pathSegments) { var root = properties.GetJsonObjectFromPath(pathSegments[0..^1]); var propertyName = pathSegments[^1]; @@ -66,7 +64,7 @@ public static class PropertiesExtensions /// The properties. /// The property path segments. /// - public static string?[]? GetStringArray(this IReadOnlyDictionary properties, Span pathSegments) + public static string?[]? GetStringArray(this IReadOnlyDictionary properties, params ReadOnlySpan pathSegments) { if (properties.TryGetValue(pathSegments[0], out var element)) { @@ -96,7 +94,7 @@ public static class PropertiesExtensions /// The properties. /// The property path segments. /// - public static string?[]? GetStringArray(this JsonElement properties, Span pathSegments) + public static string?[]? GetStringArray(this JsonElement properties, params ReadOnlySpan pathSegments) { var root = properties.GetJsonObjectFromPath(pathSegments[0..^1]); var propertyName = pathSegments[^1]; @@ -116,7 +114,7 @@ public static class PropertiesExtensions return default; } - internal static int? GetIntValue(this IReadOnlyDictionary properties, Span pathSegments) + internal static int? GetIntValue(this IReadOnlyDictionary properties, params ReadOnlySpan pathSegments) { if (properties.TryGetValue(pathSegments[0], out var element)) { @@ -132,7 +130,7 @@ public static class PropertiesExtensions return default; } - internal static int? GetIntValue(this JsonElement properties, Span pathSegments) + internal static int? GetIntValue(this JsonElement properties, params ReadOnlySpan pathSegments) { var root = properties.GetJsonObjectFromPath(pathSegments[0..^1]); var propertyName = pathSegments[^1]; @@ -148,7 +146,7 @@ public static class PropertiesExtensions return default; } - private static JsonElement GetJsonObjectFromPath(this JsonElement root, Span pathSegements) + private static JsonElement GetJsonObjectFromPath(this JsonElement root, ReadOnlySpan pathSegements) { if (pathSegements.Length == 0) return root; diff --git a/src/extensibility/dotnet-extensibility/DataModel/ResourceCatalog.cs b/src/extensibility/dotnet-extensibility/DataModel/ResourceCatalog.cs index 6f678953..a046214a 100644 --- a/src/extensibility/dotnet-extensibility/DataModel/ResourceCatalog.cs +++ b/src/extensibility/dotnet-extensibility/DataModel/ResourceCatalog.cs @@ -153,8 +153,6 @@ internal bool TryFind(ResourcePathParseResult parseResult, [NotNullWhen(true)] o } } - string[] typePath = ["type"]; - var parametersAreOK = (representation.Parameters is null && parameters is null) || @@ -164,8 +162,8 @@ internal bool TryFind(ResourcePathParseResult parseResult, [NotNullWhen(true)] o parameters.ContainsKey(current.Key) && - (current.Value.GetStringValue(typePath) == "input-integer" && long.TryParse(parameters[current.Key], out var _) || - current.Value.GetStringValue(typePath) == "select" /* no validation here */))); + (current.Value.GetStringValue("type") == "input-integer" && long.TryParse(parameters[current.Key], out var _) || + current.Value.GetStringValue("type") == "select" /* no validation here */))); if (!parametersAreOK) return false; diff --git a/src/extensibility/dotnet-extensibility/Extensibility/DataSource/DataSourceTypes.cs b/src/extensibility/dotnet-extensibility/Extensibility/DataSource/DataSourceTypes.cs index 01ea1514..a27080eb 100644 --- a/src/extensibility/dotnet-extensibility/Extensibility/DataSource/DataSourceTypes.cs +++ b/src/extensibility/dotnet-extensibility/Extensibility/DataSource/DataSourceTypes.cs @@ -58,7 +58,7 @@ internal class ReadRequestManager : IDisposable public ReadRequestManager(CatalogItem catalogItem, int elementCount) { var byteCount = elementCount * catalogItem.Representation.ElementSize; - var originalResourceName = catalogItem.Resource.Properties!.GetStringValue([DataModelExtensions.OriginalNameKey])!; + var originalResourceName = catalogItem.Resource.Properties!.GetStringValue(DataModelExtensions.OriginalNameKey)!; /* data memory */ var dataOwner = MemoryPool.Shared.Rent(byteCount); diff --git a/tests/Nexus.Tests/DataSource/SampleDataSourceTests.cs b/tests/Nexus.Tests/DataSource/SampleDataSourceTests.cs index b1e02302..555ce727 100644 --- a/tests/Nexus.Tests/DataSource/SampleDataSourceTests.cs +++ b/tests/Nexus.Tests/DataSource/SampleDataSourceTests.cs @@ -31,8 +31,8 @@ public async Task ProvidesCatalog() // assert var actualIds = actual.Resources!.Select(resource => resource.Id).ToList(); - var actualUnits = actual.Resources!.Select(resource => resource.Properties?.GetStringValue(["unit"])).ToList(); - var actualGroups = actual.Resources!.SelectMany(resource => resource.Properties?.GetStringArray(["groups"]) ?? []); + var actualUnits = actual.Resources!.Select(resource => resource.Properties?.GetStringValue(DataModelExtensions.UnitKey)).ToList(); + var actualGroups = actual.Resources!.SelectMany(resource => resource.Properties?.GetStringArray(DataModelExtensions.GroupsKey) ?? []); var actualDataTypes = actual.Resources!.SelectMany(resource => resource.Representations!.Select(representation => representation.DataType)).ToList(); var expectedIds = new List() { "T1", "V1", "unix_time1", "unix_time2" }; From 0b48ccc8344b2f4a10dfae7118e4f65cb05080ce Mon Sep 17 00:00:00 2001 From: Apollo3zehn <20972129+Apollo3zehn@users.noreply.github.com> Date: Thu, 8 Aug 2024 13:30:53 +0200 Subject: [PATCH 4/4] =?UTF-8?q?Revert=20"[Add]=20Use=20stackalloc=20in=20c?= =?UTF-8?q?ombination=20with=20the=20new=20params=20collection=20im?= =?UTF-8?q?=E2=80=A6"=20(#145)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 21e69d93f20bbcaba8891f4dba66004cd0ec9c00. --- src/Nexus/API/CatalogsController.cs | 2 +- .../DataSource/DataSourceController.cs | 7 ++----- src/Nexus/Extensions/Sources/Sample.cs | 4 ++-- src/Nexus/Extensions/Writers/Csv.cs | 10 ++++++---- src/Nexus/Services/AppStateManager.cs | 2 +- .../DataModel/DataModelExtensions.cs | 15 +++++++-------- .../DataModel/PropertiesExtensions.cs | 16 +++++++++------- .../DataModel/ResourceCatalog.cs | 6 ++++-- .../Extensibility/DataSource/DataSourceTypes.cs | 2 +- .../DataSource/SampleDataSourceTests.cs | 4 ++-- 10 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/Nexus/API/CatalogsController.cs b/src/Nexus/API/CatalogsController.cs index 69574cd8..9046611c 100644 --- a/src/Nexus/API/CatalogsController.cs +++ b/src/Nexus/API/CatalogsController.cs @@ -298,7 +298,7 @@ public async Task> if (license is null) { var catalogInfo = await catalogContainer.GetLazyCatalogInfoAsync(cancellationToken); - license = catalogInfo.Catalog.Properties?.GetStringValue(DataModelExtensions.LicenseKey); + license = catalogInfo.Catalog.Properties?.GetStringValue([DataModelExtensions.LicenseKey]); } return license; diff --git a/src/Nexus/Extensibility/DataSource/DataSourceController.cs b/src/Nexus/Extensibility/DataSource/DataSourceController.cs index fd94e370..6481ebdf 100644 --- a/src/Nexus/Extensibility/DataSource/DataSourceController.cs +++ b/src/Nexus/Extensibility/DataSource/DataSourceController.cs @@ -59,6 +59,7 @@ internal class DataSourceController( DataOptions dataOptions, ILogger logger) : IDataSourceController { + private static readonly string[] _pipelinePositionPath = [DataModelExtensions.NEXUS_KEY, DataModelExtensions.PIPELINE_POSITION_KEY]; internal readonly IReadOnlyDictionary? _requestConfiguration = requestConfiguration; @@ -421,11 +422,7 @@ private async Task ReadOriginalAsync( var currentReadRequests = readRequests .Where(request => request.CatalogItem.Resource.Properties is null || - request.CatalogItem.Resource.Properties - .GetIntValue( - DataModelExtensions.NEXUS_KEY, - DataModelExtensions.PIPELINE_POSITION_KEY - ) == pipelinePosition + request.CatalogItem.Resource.Properties.GetIntValue(_pipelinePositionPath) == pipelinePosition ) .ToArray(); diff --git a/src/Nexus/Extensions/Sources/Sample.cs b/src/Nexus/Extensions/Sources/Sample.cs index 7a4cc826..105c506c 100644 --- a/src/Nexus/Extensions/Sources/Sample.cs +++ b/src/Nexus/Extensions/Sources/Sample.cs @@ -158,8 +158,8 @@ public async Task ReadAsync( // check credentials if (catalog.Id == RemoteCatalogId) { - var user = Context.RequestConfiguration?.GetStringValue(typeof(Sample).FullName!, "user"); - var password = Context.RequestConfiguration?.GetStringValue(typeof(Sample).FullName!, "password"); + var user = Context.RequestConfiguration?.GetStringValue([typeof(Sample).FullName!, "user"]); + var password = Context.RequestConfiguration?.GetStringValue([typeof(Sample).FullName!, "password"]); if (user != RemoteUsername || password != RemotePassword) throw new Exception("The provided credentials are invalid."); diff --git a/src/Nexus/Extensions/Writers/Csv.cs b/src/Nexus/Extensions/Writers/Csv.cs index 0aebaf95..5b4eba42 100644 --- a/src/Nexus/Extensions/Writers/Csv.cs +++ b/src/Nexus/Extensions/Writers/Csv.cs @@ -26,6 +26,8 @@ namespace Nexus.Writers; "https://github.com/nexus-main/nexus/blob/master/src/Nexus/Extensions/Writers/Csv.cs")] internal class Csv : IDataWriter, IDisposable { + private static readonly string[] _unitPath = [DataModelExtensions.UnitKey]; + private const string DESCRIPTION = """ { "label":"CSV + Schema (*.csv)", @@ -112,7 +114,7 @@ public async Task OpenAsync( if (!_resourceMap.TryGetValue(resourceFilePath, out var resource)) { - var rowIndexFormat = Context.RequestConfiguration?.GetStringValue("row-index-format") ?? "index"; + var rowIndexFormat = Context.RequestConfiguration?.GetStringValue(["row-index-format"]) ?? "index"; var constraints = new Constraints(Required: true); var timestampField = rowIndexFormat switch @@ -209,9 +211,9 @@ public async Task WriteAsync(TimeSpan fileOffset, WriteRequest[] requests, IProg .GroupBy(request => request.CatalogItem.Catalog.Id) .ToList(); - var rowIndexFormat = Context.RequestConfiguration?.GetStringValue("row-index-format") ?? "index"; + var rowIndexFormat = Context.RequestConfiguration?.GetStringValue(["row-index-format"]) ?? "index"; - var significantFigures = int.Parse(Context.RequestConfiguration?.GetStringValue("significant-figures") ?? "4"); + var significantFigures = int.Parse(Context.RequestConfiguration?.GetStringValue(["significant-figures"]) ?? "4"); significantFigures = Math.Clamp(significantFigures, 0, 30); var groupIndex = 0; @@ -305,7 +307,7 @@ private static void AppendWindowsNewLine(StringBuilder stringBuilder) private static string GetFieldName(CatalogItem catalogItem) { var unit = catalogItem.Resource.Properties? - .GetStringValue(DataModelExtensions.UnitKey); + .GetStringValue(_unitPath); var fieldName = $"{catalogItem.Resource.Id}_{catalogItem.Representation.Id}{DataModelUtilities.GetRepresentationParameterString(catalogItem.Parameters)}"; diff --git a/src/Nexus/Services/AppStateManager.cs b/src/Nexus/Services/AppStateManager.cs index 8187e70c..a797a461 100644 --- a/src/Nexus/Services/AppStateManager.cs +++ b/src/Nexus/Services/AppStateManager.cs @@ -162,7 +162,7 @@ private void LoadDataWriters() } var additionalInformation = attribute.Description; - var label = (additionalInformation?.GetStringValue(UI.Core.Constants.DATA_WRITER_LABEL_KEY)) ?? throw new Exception($"The description of data writer {fullName} has no label property"); + var label = (additionalInformation?.GetStringValue([UI.Core.Constants.DATA_WRITER_LABEL_KEY])) ?? throw new Exception($"The description of data writer {fullName} has no label property"); var version = dataWriterType.Assembly .GetCustomAttribute()! .InformationalVersion; diff --git a/src/extensibility/dotnet-extensibility/DataModel/DataModelExtensions.cs b/src/extensibility/dotnet-extensibility/DataModel/DataModelExtensions.cs index 2272f787..27ae719c 100644 --- a/src/extensibility/dotnet-extensibility/DataModel/DataModelExtensions.cs +++ b/src/extensibility/dotnet-extensibility/DataModel/DataModelExtensions.cs @@ -229,19 +229,18 @@ IDataSource[] dataSources var isModified = false; var newResources = new List(); + string[] originalNamePath = [OriginalNameKey]; + string[] pipelinePositionPath = [NEXUS_KEY, PIPELINE_POSITION_KEY]; + string[] groupsPath = [GroupsKey]; + foreach (var resource in catalog.Resources) { var resourceProperties = resource.Properties; var newResource = resource; - var originalName = resourceProperties? - .GetStringValue(OriginalNameKey); - - var currentPipelinePosition = resourceProperties? - .GetIntValue(NEXUS_KEY, PIPELINE_POSITION_KEY); - - var groups = resourceProperties? - .GetStringArray(GroupsKey); + var originalName = resourceProperties?.GetStringValue(originalNamePath); + var currentPipelinePosition = resourceProperties?.GetIntValue(pipelinePositionPath); + var groups = resourceProperties?.GetStringArray(groupsPath); var distinctGroups = groups is null ? default diff --git a/src/extensibility/dotnet-extensibility/DataModel/PropertiesExtensions.cs b/src/extensibility/dotnet-extensibility/DataModel/PropertiesExtensions.cs index c0576850..2ef71984 100644 --- a/src/extensibility/dotnet-extensibility/DataModel/PropertiesExtensions.cs +++ b/src/extensibility/dotnet-extensibility/DataModel/PropertiesExtensions.cs @@ -17,8 +17,10 @@ public static class PropertiesExtensions /// The properties. /// The propery path segments. /// - public static string? GetStringValue(this IReadOnlyDictionary properties, params ReadOnlySpan pathSegments) + public static string? GetStringValue(this IReadOnlyDictionary properties, Span pathSegments) { + // TODO Maybe use params collection (Span) in future? https://github.com/dotnet/csharplang/issues/7700 + if (properties.TryGetValue(pathSegments[0], out var element)) { pathSegments = pathSegments[1..]; @@ -42,7 +44,7 @@ public static class PropertiesExtensions /// The properties. /// The propery path segments. /// - public static string? GetStringValue(this JsonElement properties, params ReadOnlySpan pathSegments) + public static string? GetStringValue(this JsonElement properties, Span pathSegments) { var root = properties.GetJsonObjectFromPath(pathSegments[0..^1]); var propertyName = pathSegments[^1]; @@ -64,7 +66,7 @@ public static class PropertiesExtensions /// The properties. /// The property path segments. /// - public static string?[]? GetStringArray(this IReadOnlyDictionary properties, params ReadOnlySpan pathSegments) + public static string?[]? GetStringArray(this IReadOnlyDictionary properties, Span pathSegments) { if (properties.TryGetValue(pathSegments[0], out var element)) { @@ -94,7 +96,7 @@ public static class PropertiesExtensions /// The properties. /// The property path segments. /// - public static string?[]? GetStringArray(this JsonElement properties, params ReadOnlySpan pathSegments) + public static string?[]? GetStringArray(this JsonElement properties, Span pathSegments) { var root = properties.GetJsonObjectFromPath(pathSegments[0..^1]); var propertyName = pathSegments[^1]; @@ -114,7 +116,7 @@ public static class PropertiesExtensions return default; } - internal static int? GetIntValue(this IReadOnlyDictionary properties, params ReadOnlySpan pathSegments) + internal static int? GetIntValue(this IReadOnlyDictionary properties, Span pathSegments) { if (properties.TryGetValue(pathSegments[0], out var element)) { @@ -130,7 +132,7 @@ public static class PropertiesExtensions return default; } - internal static int? GetIntValue(this JsonElement properties, params ReadOnlySpan pathSegments) + internal static int? GetIntValue(this JsonElement properties, Span pathSegments) { var root = properties.GetJsonObjectFromPath(pathSegments[0..^1]); var propertyName = pathSegments[^1]; @@ -146,7 +148,7 @@ public static class PropertiesExtensions return default; } - private static JsonElement GetJsonObjectFromPath(this JsonElement root, ReadOnlySpan pathSegements) + private static JsonElement GetJsonObjectFromPath(this JsonElement root, Span pathSegements) { if (pathSegements.Length == 0) return root; diff --git a/src/extensibility/dotnet-extensibility/DataModel/ResourceCatalog.cs b/src/extensibility/dotnet-extensibility/DataModel/ResourceCatalog.cs index a046214a..6f678953 100644 --- a/src/extensibility/dotnet-extensibility/DataModel/ResourceCatalog.cs +++ b/src/extensibility/dotnet-extensibility/DataModel/ResourceCatalog.cs @@ -153,6 +153,8 @@ internal bool TryFind(ResourcePathParseResult parseResult, [NotNullWhen(true)] o } } + string[] typePath = ["type"]; + var parametersAreOK = (representation.Parameters is null && parameters is null) || @@ -162,8 +164,8 @@ internal bool TryFind(ResourcePathParseResult parseResult, [NotNullWhen(true)] o parameters.ContainsKey(current.Key) && - (current.Value.GetStringValue("type") == "input-integer" && long.TryParse(parameters[current.Key], out var _) || - current.Value.GetStringValue("type") == "select" /* no validation here */))); + (current.Value.GetStringValue(typePath) == "input-integer" && long.TryParse(parameters[current.Key], out var _) || + current.Value.GetStringValue(typePath) == "select" /* no validation here */))); if (!parametersAreOK) return false; diff --git a/src/extensibility/dotnet-extensibility/Extensibility/DataSource/DataSourceTypes.cs b/src/extensibility/dotnet-extensibility/Extensibility/DataSource/DataSourceTypes.cs index a27080eb..01ea1514 100644 --- a/src/extensibility/dotnet-extensibility/Extensibility/DataSource/DataSourceTypes.cs +++ b/src/extensibility/dotnet-extensibility/Extensibility/DataSource/DataSourceTypes.cs @@ -58,7 +58,7 @@ internal class ReadRequestManager : IDisposable public ReadRequestManager(CatalogItem catalogItem, int elementCount) { var byteCount = elementCount * catalogItem.Representation.ElementSize; - var originalResourceName = catalogItem.Resource.Properties!.GetStringValue(DataModelExtensions.OriginalNameKey)!; + var originalResourceName = catalogItem.Resource.Properties!.GetStringValue([DataModelExtensions.OriginalNameKey])!; /* data memory */ var dataOwner = MemoryPool.Shared.Rent(byteCount); diff --git a/tests/Nexus.Tests/DataSource/SampleDataSourceTests.cs b/tests/Nexus.Tests/DataSource/SampleDataSourceTests.cs index 555ce727..b1e02302 100644 --- a/tests/Nexus.Tests/DataSource/SampleDataSourceTests.cs +++ b/tests/Nexus.Tests/DataSource/SampleDataSourceTests.cs @@ -31,8 +31,8 @@ public async Task ProvidesCatalog() // assert var actualIds = actual.Resources!.Select(resource => resource.Id).ToList(); - var actualUnits = actual.Resources!.Select(resource => resource.Properties?.GetStringValue(DataModelExtensions.UnitKey)).ToList(); - var actualGroups = actual.Resources!.SelectMany(resource => resource.Properties?.GetStringArray(DataModelExtensions.GroupsKey) ?? []); + var actualUnits = actual.Resources!.Select(resource => resource.Properties?.GetStringValue(["unit"])).ToList(); + var actualGroups = actual.Resources!.SelectMany(resource => resource.Properties?.GetStringArray(["groups"]) ?? []); var actualDataTypes = actual.Resources!.SelectMany(resource => resource.Representations!.Select(representation => representation.DataType)).ToList(); var expectedIds = new List() { "T1", "V1", "unix_time1", "unix_time2" };