From 4ec013254f05b874a05800d0ad4d40d41b6e4afc Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Tue, 2 Jan 2024 18:57:06 +0100 Subject: [PATCH 001/352] added benchmark artifact folder to .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3c4efe20..76a9d5ac 100644 --- a/.gitignore +++ b/.gitignore @@ -258,4 +258,5 @@ paket-files/ # Python Tools for Visual Studio (PTVS) __pycache__/ -*.pyc \ No newline at end of file +*.pyc +/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/BenchmarkDotNet.Artifacts/results From d8a98fb255b795e40b641850bc6cf6d08fe53169 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Tue, 2 Jan 2024 18:57:38 +0100 Subject: [PATCH 002/352] added BenchmarkDotNet artifact folder to .gitignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 76a9d5ac..88197d63 100644 --- a/.gitignore +++ b/.gitignore @@ -259,4 +259,6 @@ paket-files/ # Python Tools for Visual Studio (PTVS) __pycache__/ *.pyc -/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/BenchmarkDotNet.Artifacts/results + +# BenchmarkDotNet artifacts +**/BenchmarkDotNet.Artifacts/ From 215c89b3ee09db278b4608f208c6925018c6af01 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Tue, 2 Jan 2024 18:58:41 +0100 Subject: [PATCH 003/352] refactored core implementation, added dependency injection project, updated benchmarks and tests --- DropoutCoder.PolylineAlgorithm.sln | 20 +- ...tCoder.PolylineAlgorithm.Benchmarks.csproj | 2 +- .../PolylineEncodingBenchmark.cs | 23 +- .../Program.cs | 7 +- .../DecodePerformanceBenchmark.cs | 129 ++++++++++- ...Algorithm.Implementation.Benchmarks.csproj | 4 - .../EncodePerformanceBenchmark.cs | 140 +++++++++++- .../Program.cs | 7 +- ...lylineAlgorithm.DependencyInjection.csproj | 16 ++ .../ServiceCollectionExtensions.cs | 27 +++ src/DropoutCoder.PolylineAlgorithm.csproj | 29 --- .../DefaultCoordinateValidator.cs | 33 +++ .../DefaultPolylineEncoder.cs} | 20 +- .../DropoutCoder.PolylineAlgorithm.csproj | 30 +++ .../ExceptionMessageResource.Designer.cs | 0 .../ExceptionMessageResource.resx | 0 .../ICoordinateValidator.cs | 12 + .../IPolylineEncoder.cs} | 10 +- .../Internal}/Constants.cs | 2 +- .../PolylineEncoder.cs | 183 +++++++++++++++ src/Encoding/PolylineEncodingBase.cs | 72 ------ src/PolylineAlgorithm.cs | 216 ------------------ src/Validation/CoordinateValidator.cs | 47 ---- ...Algorithm.DependencyInjection.Tests.csproj | 24 ++ .../GlobalUsings.cs | 6 + .../ServiceCollectionExtensionsTests.cs | 52 +++++ .../CoordinateValidatorTest.cs | 65 ++++++ .../Defaults.cs | 0 ...ropoutCoder.PolylineAlgorithm.Tests.csproj | 2 +- .../GlobalUsings.cs | 9 + .../PolylineAlgorithmTest.cs | 30 +-- .../Properties/AssemblyInfo.cs | 0 tests/Encoding/PolylineEncodingBaseTest.cs | 196 ---------------- tests/Encoding/PolylineEncodingTest.cs | 55 ----- tests/Validation/CoordinateValidatorTest.cs | 136 ----------- 35 files changed, 787 insertions(+), 817 deletions(-) create mode 100644 src/DropoutCoder.PolylineAlgorithm.DependencyInjection/DropoutCoder.PolylineAlgorithm.DependencyInjection.csproj create mode 100644 src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs delete mode 100644 src/DropoutCoder.PolylineAlgorithm.csproj create mode 100644 src/DropoutCoder.PolylineAlgorithm/DefaultCoordinateValidator.cs rename src/{Encoding/PolylineEncoding.cs => DropoutCoder.PolylineAlgorithm/DefaultPolylineEncoder.cs} (68%) create mode 100644 src/DropoutCoder.PolylineAlgorithm/DropoutCoder.PolylineAlgorithm.csproj rename src/{ => DropoutCoder.PolylineAlgorithm}/ExceptionMessageResource.Designer.cs (100%) rename src/{ => DropoutCoder.PolylineAlgorithm}/ExceptionMessageResource.resx (100%) create mode 100644 src/DropoutCoder.PolylineAlgorithm/ICoordinateValidator.cs rename src/{Encoding/IPolylineEncoding.cs => DropoutCoder.PolylineAlgorithm/IPolylineEncoder.cs} (85%) rename src/{ => DropoutCoder.PolylineAlgorithm/Internal}/Constants.cs (97%) create mode 100644 src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs delete mode 100644 src/Encoding/PolylineEncodingBase.cs delete mode 100644 src/PolylineAlgorithm.cs delete mode 100644 src/Validation/CoordinateValidator.cs create mode 100644 tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj create mode 100644 tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs create mode 100644 tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs create mode 100644 tests/DropoutCoder.PolylineAlgorithm.Tests/CoordinateValidatorTest.cs rename tests/{ => DropoutCoder.PolylineAlgorithm.Tests}/Defaults.cs (100%) rename tests/{ => DropoutCoder.PolylineAlgorithm.Tests}/DropoutCoder.PolylineAlgorithm.Tests.csproj (84%) create mode 100644 tests/DropoutCoder.PolylineAlgorithm.Tests/GlobalUsings.cs rename tests/{ => DropoutCoder.PolylineAlgorithm.Tests}/PolylineAlgorithmTest.cs (87%) rename tests/{ => DropoutCoder.PolylineAlgorithm.Tests}/Properties/AssemblyInfo.cs (100%) delete mode 100644 tests/Encoding/PolylineEncodingBaseTest.cs delete mode 100644 tests/Encoding/PolylineEncodingTest.cs delete mode 100644 tests/Validation/CoordinateValidatorTest.cs diff --git a/DropoutCoder.PolylineAlgorithm.sln b/DropoutCoder.PolylineAlgorithm.sln index a7673087..ffaeb45b 100644 --- a/DropoutCoder.PolylineAlgorithm.sln +++ b/DropoutCoder.PolylineAlgorithm.sln @@ -2,7 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.8.34330.188 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm", "src\DropoutCoder.PolylineAlgorithm.csproj", "{882322A6-E758-4662-8D1C-7C555C8FC3F2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm", "src\DropoutCoder.PolylineAlgorithm\DropoutCoder.PolylineAlgorithm.csproj", "{882322A6-E758-4662-8D1C-7C555C8FC3F2}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{51C886AF-D610-48A4-9D73-2DEB38742801}" EndProject @@ -13,7 +13,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nuget", "nuget", "{7F9807A1 nuget\DropoutCoder.PolylineAlgorithm.nuspec = nuget\DropoutCoder.PolylineAlgorithm.nuspec EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm.Tests", "tests\DropoutCoder.PolylineAlgorithm.Tests.csproj", "{30324A08-AA42-425D-87DA-8F9C6AF60454}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm.Tests", "tests\DropoutCoder.PolylineAlgorithm.Tests\DropoutCoder.PolylineAlgorithm.Tests.csproj", "{30324A08-AA42-425D-87DA-8F9C6AF60454}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{C13E31F9-B8EF-4915-A1C8-BC33F6431EB9}" EndProject @@ -21,7 +21,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm.Benchmarks", "benchmarks\DropoutCoder.PolylineAlgorithm.Benchmarks\DropoutCoder.PolylineAlgorithm.Benchmarks.csproj", "{9C7CBAD5-415B-4589-86E1-01C849F9C56C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks", "benchmarks\DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks\DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks.csproj", "{D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks", "benchmarks\DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks\DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks.csproj", "{D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm.DependencyInjection", "src\DropoutCoder.PolylineAlgorithm.DependencyInjection\DropoutCoder.PolylineAlgorithm.DependencyInjection.csproj", "{0F07B56B-6D9A-4410-BCAB-C6A460C1E44E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests", "tests\DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests\DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj", "{9DC1BAD9-60DD-414D-BE88-E181D887A267}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -45,6 +49,14 @@ Global {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}.Debug|Any CPU.Build.0 = Debug|Any CPU {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}.Release|Any CPU.ActiveCfg = Release|Any CPU {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}.Release|Any CPU.Build.0 = Release|Any CPU + {0F07B56B-6D9A-4410-BCAB-C6A460C1E44E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F07B56B-6D9A-4410-BCAB-C6A460C1E44E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F07B56B-6D9A-4410-BCAB-C6A460C1E44E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F07B56B-6D9A-4410-BCAB-C6A460C1E44E}.Release|Any CPU.Build.0 = Release|Any CPU + {9DC1BAD9-60DD-414D-BE88-E181D887A267}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9DC1BAD9-60DD-414D-BE88-E181D887A267}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9DC1BAD9-60DD-414D-BE88-E181D887A267}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9DC1BAD9-60DD-414D-BE88-E181D887A267}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -54,6 +66,8 @@ Global {30324A08-AA42-425D-87DA-8F9C6AF60454} = {576FEFFC-B624-40C3-A8AF-4E5233802EA0} {9C7CBAD5-415B-4589-86E1-01C849F9C56C} = {33C03F16-4313-4579-87E6-65892AF21D7D} {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B} = {33C03F16-4313-4579-87E6-65892AF21D7D} + {0F07B56B-6D9A-4410-BCAB-C6A460C1E44E} = {51C886AF-D610-48A4-9D73-2DEB38742801} + {9DC1BAD9-60DD-414D-BE88-E181D887A267} = {576FEFFC-B624-40C3-A8AF-4E5233802EA0} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {93A268DC-0947-4FBB-B495-DDAD4B013D82} diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks.csproj b/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks.csproj index 2d5b8cc1..3b478512 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks.csproj +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks.csproj @@ -12,7 +12,7 @@ - + diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs index 798fd3ae..5dcaa08d 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs @@ -1,8 +1,13 @@ -namespace DropoutCoder.PolylineAlgorithm.Benchmarks +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace DropoutCoder.PolylineAlgorithm.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; - using DropoutCoder.PolylineAlgorithm.Encoding; + using DropoutCoder.PolylineAlgorithm; [MemoryDiagnoser] [MarkdownExporter] @@ -10,30 +15,30 @@ public class PolylineEncodingBenchmark { private Consumer _consumer = new Consumer(); - [Params(10_000, 100_000, 1_000_000, Priority = 2)] + [Params(1_000, 100_000, 10_000_000, Priority = 2)] public int N; public IEnumerable<(double, double)> Coordinates; - public PolylineEncoding Encoding { get; private set; } + internal DefaultPolylineEncoder Encoder { get; private set; } - public string Polyline; + public char[] Polyline; [GlobalSetup] public void Setup() { - Encoding = new PolylineEncoding(); + Encoder = new DefaultPolylineEncoder(new DefaultCoordinateValidator()); Coordinates = new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }; - Polyline = "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; + Polyline = "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB".ToCharArray(); } [Benchmark] - public void Decode() => Encoding + public void Decode() => Encoder .Decode(Polyline) .Consume(_consumer); [Benchmark] - public void Encode() => Encoding + public void Encode() => Encoder .Encode(Coordinates) .Consume(_consumer); } diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/Program.cs index d6e3655e..30b8f4a5 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/Program.cs @@ -1,4 +1,9 @@ -namespace DropoutCoder.PolylineAlgorithm.Benchmarks +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace DropoutCoder.PolylineAlgorithm.Benchmarks { using BenchmarkDotNet.Running; diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs index 43289f5d..acd4ba8f 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs @@ -1,4 +1,9 @@ -namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; @@ -19,17 +24,13 @@ public class DecodePerformanceBenchmark [ArgumentsSource(nameof(Polylines))] public void Decode_V1((int, char[]) arg) => V1.Decode(arg.Item2).Consume(_consumer); - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V1_Parallel((int, char[]) arg) => Parallel.For(0, 100, (i) => V1.Decode(arg.Item2).Consume(_consumer)); - [Benchmark] [ArgumentsSource(nameof(Polylines))] public void Decode_V2((int, char[]) arg) => V2.Decode(arg.Item2).Consume(_consumer); [Benchmark] [ArgumentsSource(nameof(Polylines))] - public void Decode_V2_Parallel((int, char[]) arg) => Parallel.For(0, 100, (i) => V2.Decode(arg.Item2).Consume(_consumer)); + public void Decode_V3((int, char[]) arg) => V3.Decode(arg.Item2).Consume(_consumer); private class V1 { @@ -196,5 +197,121 @@ public static bool IsValidLongitude(double longitude) } } } + + private class V3 + { + public static IEnumerable<(double Latitude, double Longitude)> Decode(char[] polyline) + { + // Checking null and at least one character + if (polyline == null || polyline.Length == 0) + { + throw new ArgumentException(nameof(polyline)); + } + + // Initialize local variables + int index = 0; + int latitude = 0; + int longitude = 0; + + // Looping through encoded polyline char array + while (index < polyline.Length) + { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref latitude)) + { + throw new InvalidOperationException(); + } + + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref longitude)) + { + throw new InvalidOperationException(); + } + + var coordinate = CreateResult(GetCoordinate(latitude), GetCoordinate(longitude)); + + if (!Validator.IsValid(coordinate)) + { + throw new InvalidOperationException(); + } + + yield return coordinate; + + + #region Local functions + + bool TryCalculateNext(char[] polyline, ref int index, ref int value) + { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; + + do + { + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + double GetCoordinate(int value) + { + return Convert.ToDouble(value) / Constants.Precision; + } + + #endregion + } + } + + protected static (double Latitude, double Longitude) CreateResult(double latitude, double longitude) + { + return (latitude, longitude); + } + + public static class Validator + { + #region Methods + + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValid((double Latitude, double Longitude) coordinate) + { + return IsValidLatitude(ref coordinate.Latitude) && IsValidLongitude(ref coordinate.Longitude); + } + + /// + /// Performs latitude validation + /// + /// Latitude value to validate + /// Returns validation result. If valid then true, otherwise false. + private static bool IsValidLatitude(ref readonly double latitude) + { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + /// + /// Performs longitude validation + /// + /// Longitude value to validate + /// Returns validation result. If valid then true, otherwise false. + private static bool IsValidLongitude(ref readonly double longitude) + { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + + #endregion + } + } } } diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks.csproj b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks.csproj index d799ba3b..03de0360 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks.csproj +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks.csproj @@ -12,8 +12,4 @@ - - - - diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs index d7a75e02..1d441be6 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs @@ -1,4 +1,9 @@ -namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; @@ -22,19 +27,13 @@ public class EncodePerformanceBenchmark [ArgumentsSource(nameof(Coordinates))] public void Encode_V1((int, IEnumerable<(double, double)>) arg) => V1.Encode(arg.Item2).Consume(_consumer); - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public void Encode_V1_Parallel((int, IEnumerable<(double, double)>) arg) => Parallel.For(100, 200, (i) => V1.Encode(arg.Item2).Consume(_consumer)); - - [Benchmark] [ArgumentsSource(nameof(Coordinates))] public void Encode_V2((int, IEnumerable<(double, double)>) arg) => V2.Encode(arg.Item2).Consume(_consumer); - [Benchmark] [ArgumentsSource(nameof(Coordinates))] - public void Encode_V2_Parallel((int, IEnumerable<(double, double)>) arg) => Parallel.For(100, 200, (i) => V2.Encode(arg.Item2).Consume(_consumer)); + public void Encode_V3((int, IEnumerable<(double, double)>) arg) => V3.Encode(arg.Item2).Consume(_consumer); private class V1 { @@ -218,5 +217,130 @@ public static bool IsValidLongitude(double longitude) } } } + + private class V3 + { + private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, int.MaxValue); + + public static string Encode(IEnumerable<(double Latitude, double Longitude)> collection) + { + if (collection == null || !collection.GetEnumerator().MoveNext()) + { + throw new ArgumentException(nameof(collection)); + } + + // Validate collection of coordinates + if (!TryValidate(collection, out var invalid)) + { + throw new ArgumentException(nameof(collection)); + } + + // Initializing local variables + int previousLatitude = 0; + int previousLongitude = 0; + var sb = _pool.Get(); + + // Looping over coordinates and building encoded result + foreach (var item in collection) + { + var coordinate = GetCoordinate(item); + + int latitude = Round(coordinate.Latitude); + int longitude = Round(coordinate.Longitude); + + sb.Append(GetSequence(latitude - previousLatitude).ToArray()); + sb.Append(GetSequence(longitude - previousLongitude).ToArray()); + + previousLatitude = latitude; + previousLongitude = longitude; + } + + var result = sb.ToString(); + + _pool.Return(sb); + + return result; + + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection<(double Latitude, double Longitude)> validationErrors) + { + validationErrors = new List<(double Latitude, double Longitude)>(); + + foreach (var item in collection) + { + if (!Validator.IsValid(item)) + { + validationErrors.Add(item); + } + } + + return !validationErrors.GetEnumerator().MoveNext(); + } + + int Round(double value) + { + return (int)Math.Round(value * Constants.Precision); + } + + IEnumerable GetSequence(int value) + { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) + { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + + rem >>= Constants.ShiftLength; + } + + yield return (char)(rem + Constants.ASCII.QuestionMark); + } + } + + protected static (double Latitude, double Longitude) GetCoordinate((double Latitude, double Longitude) value) + { + return value; + } + + public static class Validator + { + #region Methods + + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValid((double Latitude, double Longitude) coordinate) + { + return IsValidLatitude(ref coordinate.Latitude) && IsValidLongitude(ref coordinate.Longitude); + } + + /// + /// Performs latitude validation + /// + /// Latitude value to validate + /// Returns validation result. If valid then true, otherwise false. + private static bool IsValidLatitude(ref readonly double latitude) + { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + /// + /// Performs longitude validation + /// + /// Longitude value to validate + /// Returns validation result. If valid then true, otherwise false. + private static bool IsValidLongitude(ref readonly double longitude) + { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + + #endregion + } + } } } diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Program.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Program.cs index 1a591c1c..de91106e 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Program.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Program.cs @@ -1,4 +1,9 @@ -namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks { using BenchmarkDotNet.Running; diff --git a/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/DropoutCoder.PolylineAlgorithm.DependencyInjection.csproj b/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/DropoutCoder.PolylineAlgorithm.DependencyInjection.csproj new file mode 100644 index 00000000..87f8a411 --- /dev/null +++ b/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/DropoutCoder.PolylineAlgorithm.DependencyInjection.csproj @@ -0,0 +1,16 @@ + + + + netstandard2.1 + enable + + + + + + + + + + + diff --git a/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs b/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs new file mode 100644 index 00000000..f2d9c4c5 --- /dev/null +++ b/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs @@ -0,0 +1,27 @@ +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace DropoutCoder.PolylineAlgorithm.DependencyInjection +{ + using Microsoft.Extensions.DependencyInjection; + + public static class ServiceCollectionExtensions + { + public static IServiceCollection AddDefaultPolylineEncoder(this IServiceCollection services) + { + return services + .AddPolylineEncoder(); + } + + public static IServiceCollection AddPolylineEncoder(this IServiceCollection services) + where TEncoder : class, IPolylineEncoder + where TValidator : class, ICoordinateValidator + { + return services + .AddSingleton, TValidator>() + .AddSingleton, TEncoder>(); + } + } +} diff --git a/src/DropoutCoder.PolylineAlgorithm.csproj b/src/DropoutCoder.PolylineAlgorithm.csproj deleted file mode 100644 index 9972fb37..00000000 --- a/src/DropoutCoder.PolylineAlgorithm.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - net8.0 - - - - - - - - - - - - - - - True - True - ExceptionMessageResource.resx - - - - - ResXFileCodeGenerator - ExceptionMessageResource.Designer.cs - - - \ No newline at end of file diff --git a/src/DropoutCoder.PolylineAlgorithm/DefaultCoordinateValidator.cs b/src/DropoutCoder.PolylineAlgorithm/DefaultCoordinateValidator.cs new file mode 100644 index 00000000..6c828a98 --- /dev/null +++ b/src/DropoutCoder.PolylineAlgorithm/DefaultCoordinateValidator.cs @@ -0,0 +1,33 @@ +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +using DropoutCoder.PolylineAlgorithm.Internal; + +namespace DropoutCoder.PolylineAlgorithm +{ + using System; + using System.Runtime.CompilerServices; + + /// + /// Performs coordinate validation + /// + public class DefaultCoordinateValidator : ICoordinateValidator<(double Latitude, double Longitude)> + { + #region Methods + + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsValid((double Latitude, double Longitude) coordinate) + { + return Math.Abs(coordinate.Latitude) <= Constants.Coordinate.MaxLatitude && Math.Abs(coordinate.Longitude) <= Constants.Coordinate.MaxLongitude; + } + + #endregion + } +} diff --git a/src/Encoding/PolylineEncoding.cs b/src/DropoutCoder.PolylineAlgorithm/DefaultPolylineEncoder.cs similarity index 68% rename from src/Encoding/PolylineEncoding.cs rename to src/DropoutCoder.PolylineAlgorithm/DefaultPolylineEncoder.cs index 058d56e5..79bd9775 100644 --- a/src/Encoding/PolylineEncoding.cs +++ b/src/DropoutCoder.PolylineAlgorithm/DefaultPolylineEncoder.cs @@ -3,14 +3,14 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Encoding +namespace DropoutCoder.PolylineAlgorithm { - /// - /// Defines default polyline encoding with generic - /// - public class PolylineEncoding : PolylineEncodingBase<(double Latitude, double Longitude)> + using System.Runtime.CompilerServices; + + public sealed class DefaultPolylineEncoder : PolylineEncoder<(double Latitude, double Longitude)> { - #region Methods + public DefaultPolylineEncoder(ICoordinateValidator<(double Latitude, double Longitude)> validator) + : base(validator) { } /// /// Method creates result from passed latitude and longitude arguments @@ -18,6 +18,7 @@ public class PolylineEncoding : PolylineEncodingBase<(double Latitude, double Lo /// Latitude value /// Longitude value /// Returns created instance of + [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override (double Latitude, double Longitude) CreateResult(double latitude, double longitude) { return (latitude, longitude); @@ -28,11 +29,10 @@ protected override (double Latitude, double Longitude) CreateResult(double latit /// /// The /// Returns created coordinate - protected override (double Latitude, double Longitude) GetCoordinate((double Latitude, double Longitude) source) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected override (double Latitude, double Longitude) GetCoordinate((double Latitude, double Longitude) value) { - return source; + return value; } - - #endregion } } diff --git a/src/DropoutCoder.PolylineAlgorithm/DropoutCoder.PolylineAlgorithm.csproj b/src/DropoutCoder.PolylineAlgorithm/DropoutCoder.PolylineAlgorithm.csproj new file mode 100644 index 00000000..129df9d6 --- /dev/null +++ b/src/DropoutCoder.PolylineAlgorithm/DropoutCoder.PolylineAlgorithm.csproj @@ -0,0 +1,30 @@ + + + netstandard2.1 + enable + + + + <_Parameter1>DropoutCoder.PolylineAlgorithm.Tests + + + <_Parameter1>DropoutCoder.PolylineAlgorithm.Benchmarks + + + + + + + + True + True + ExceptionMessageResource.resx + + + + + ResXFileCodeGenerator + ExceptionMessageResource.Designer.cs + + + \ No newline at end of file diff --git a/src/ExceptionMessageResource.Designer.cs b/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.Designer.cs similarity index 100% rename from src/ExceptionMessageResource.Designer.cs rename to src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.Designer.cs diff --git a/src/ExceptionMessageResource.resx b/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.resx similarity index 100% rename from src/ExceptionMessageResource.resx rename to src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.resx diff --git a/src/DropoutCoder.PolylineAlgorithm/ICoordinateValidator.cs b/src/DropoutCoder.PolylineAlgorithm/ICoordinateValidator.cs new file mode 100644 index 00000000..2a6bf553 --- /dev/null +++ b/src/DropoutCoder.PolylineAlgorithm/ICoordinateValidator.cs @@ -0,0 +1,12 @@ +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace DropoutCoder.PolylineAlgorithm +{ + public interface ICoordinateValidator + { + bool IsValid(T coordinate); + } +} diff --git a/src/Encoding/IPolylineEncoding.cs b/src/DropoutCoder.PolylineAlgorithm/IPolylineEncoder.cs similarity index 85% rename from src/Encoding/IPolylineEncoding.cs rename to src/DropoutCoder.PolylineAlgorithm/IPolylineEncoder.cs index 82348ac5..31b52872 100644 --- a/src/Encoding/IPolylineEncoding.cs +++ b/src/DropoutCoder.PolylineAlgorithm/IPolylineEncoder.cs @@ -3,17 +3,15 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Encoding +namespace DropoutCoder.PolylineAlgorithm { using System.Collections.Generic; - #region Interfaces - /// /// Defines base interface for all polyline encodings /// /// Desired type used to decode to and encode from - public interface IPolylineEncoding + public interface IPolylineEncoder { #region Methods @@ -22,7 +20,7 @@ public interface IPolylineEncoding /// /// Encoded coordinates /// The - IEnumerable Decode(string source); + IEnumerable Decode(char[] source); /// /// Method performs encoding from generic type to polyline encoded @@ -33,6 +31,4 @@ public interface IPolylineEncoding #endregion } - - #endregion } diff --git a/src/Constants.cs b/src/DropoutCoder.PolylineAlgorithm/Internal/Constants.cs similarity index 97% rename from src/Constants.cs rename to src/DropoutCoder.PolylineAlgorithm/Internal/Constants.cs index b05a5029..6b498cce 100644 --- a/src/Constants.cs +++ b/src/DropoutCoder.PolylineAlgorithm/Internal/Constants.cs @@ -3,7 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm +namespace DropoutCoder.PolylineAlgorithm.Internal { /// /// Defines global constant values diff --git a/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs b/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs new file mode 100644 index 00000000..622f0816 --- /dev/null +++ b/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs @@ -0,0 +1,183 @@ +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace DropoutCoder.PolylineAlgorithm +{ + using DropoutCoder.PolylineAlgorithm.Internal; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Runtime.CompilerServices; + using System.Text; + + public abstract class PolylineEncoder : IPolylineEncoder + { + private static Lazy _default = new Lazy(() => new DefaultPolylineEncoder(new DefaultCoordinateValidator())); + + public static IPolylineEncoder<(double Latitude, double Longitude)> Default => _default.Value; + + public ICoordinateValidator Validator { get; } + + public PolylineEncoder(ICoordinateValidator validator) + { + Validator = validator; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public IEnumerable Decode(char[] polyline) + { + // Checking null and at least one character + if (polyline == null || polyline.Length == 0) + { + throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(polyline)); + } + + // Initialize local variables + int index = 0; + int latitude = 0; + int longitude = 0; + + // Looping through encoded polyline char array + while (index < polyline.Length) + { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref latitude)) + { + throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); + } + + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref longitude)) + { + throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); + } + + var coordinate = CreateResult(GetCoordinate(latitude), GetCoordinate(longitude)); + + if (!Validator.IsValid(coordinate)) + { + throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); + } + + yield return coordinate; + + + #region Local functions + + bool TryCalculateNext(char[] polyline, ref int index, ref int value) + { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; + + do + { + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + double GetCoordinate(int value) + { + return Convert.ToDouble(value) / Constants.Precision; + } + + #endregion + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public string Encode(IEnumerable collection) + { + if (collection == null || !collection.GetEnumerator().MoveNext()) + { + throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(collection)); + } + + // Validate collection of coordinates + if (!TryValidate(collection, out var invalid)) + { + throw new ArgumentException(ExceptionMessageResource.AggregateExceptionCoordinatesAreInvalidErrorMessage, nameof(collection)); + } + + // Initializing local variables + int previousLatitude = 0; + int previousLongitude = 0; + var sb = new StringBuilder(); + + // Looping over coordinates and building encoded result + foreach (var item in collection) + { + var coordinate = GetCoordinate(item); + + int latitude = Round(coordinate.Latitude); + int longitude = Round(coordinate.Longitude); + + sb.Append(GetSequence(latitude - previousLatitude).ToArray()); + sb.Append(GetSequence(longitude - previousLongitude).ToArray()); + + previousLatitude = latitude; + previousLongitude = longitude; + } + + var result = sb.ToString(); + + return result; + + bool TryValidate(IEnumerable collection, out ICollection validationErrors) + { + validationErrors = new List(); + + foreach (var item in collection) + { + if (!Validator.IsValid(item)) + { + validationErrors.Add(item); + } + } + + return !validationErrors.GetEnumerator().MoveNext(); + } + + int Round(double value) + { + return (int)Math.Round(value * Constants.Precision); + } + + IEnumerable GetSequence(int value) + { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) + { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + + rem >>= Constants.ShiftLength; + } + + yield return (char)(rem + Constants.ASCII.QuestionMark); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected abstract T CreateResult(double latitude, double longitude); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected abstract (double Latitude, double Longitude) GetCoordinate(T value); + } +} diff --git a/src/Encoding/PolylineEncodingBase.cs b/src/Encoding/PolylineEncodingBase.cs deleted file mode 100644 index b3de4cfb..00000000 --- a/src/Encoding/PolylineEncodingBase.cs +++ /dev/null @@ -1,72 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace DropoutCoder.PolylineAlgorithm.Encoding -{ - using System; - using System.Collections.Generic; - using System.Linq; - - /// /// - /// Defines base class for all polyline encodings - /// - /// - public abstract class PolylineEncodingBase : IPolylineEncoding - { - #region Methods - - /// - /// Method performs decode operation and coversion to desired type - /// - /// The - /// The - public IEnumerable Decode(string source) - { - if (string.IsNullOrEmpty(source)) - { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(source)); - } - - char[] polyline = source.ToCharArray(); - - return PolylineAlgorithm.Decode(polyline) - .Select(c => CreateResult(c.Latitude, c.Longitude)); - } - - /// - /// Method performs conversion to coordinate tuple and encode operation. - /// - /// The - /// The - public string Encode(IEnumerable source) - { - if (source == null || !source.Any()) - { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(source)); - } - - var coordinates = source.Select(s => GetCoordinate(s)); - - return PolylineAlgorithm.Encode(coordinates); - } - - /// - /// Method creates result from passed latitude and longitude arguments - /// - /// Latitude value - /// Longitude value - /// Returns created instance of - protected abstract T CreateResult(double latitude, double longitude); - - /// - /// The GetCoordinates - /// - /// The - /// The - protected abstract (double Latitude, double Longitude) GetCoordinate(T source); - - #endregion - } -} diff --git a/src/PolylineAlgorithm.cs b/src/PolylineAlgorithm.cs deleted file mode 100644 index 1f700191..00000000 --- a/src/PolylineAlgorithm.cs +++ /dev/null @@ -1,216 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace DropoutCoder.PolylineAlgorithm -{ - using DropoutCoder.PolylineAlgorithm.Validation; - using Microsoft.Extensions.ObjectPool; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - - /// - /// Performs polyline algorithm decoding and encoding - /// - public static class PolylineAlgorithm - { - private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); - - #region Methods - - /// - /// Method decodes polyline encoded representation to coordinates. - /// - /// Encoded polyline char array to decode - /// Returns coordinates. - /// If polyline argument is null -or- empty char array. - /// If polyline representation is not in correct format. - public static IEnumerable<(double Latitude, double Longitude)> Decode(char[] polyline) - { - // Checking null and at least one character - if (polyline == null || !polyline.Any()) - { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(polyline)); - } - - // Initialize local variables - int index = 0; - int latitude = 0; - int longitude = 0; - - // Looping through encoded polyline char array - while (index < polyline.Length) - { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref latitude)) - { - throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); - } - - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref longitude)) - { - throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); - } - - var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); - - if (!CoordinateValidator.IsValid(coordinate)) - { - throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); - } - - yield return coordinate; - } - } - - /// - /// Method encodes coordinates to polyline encoded representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) - { - if (coordinates == null || !coordinates.Any()) - { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(coordinates)); - } - - // Ensuring coordinates are valid, otherwise throws an aggregate exception - EnsureCoordinates(coordinates); - - // Initializing local variables - int previousLatitude = 0; - int previousLongitude = 0; - var sb = _pool.Get(); - - // Looping over coordinates and building encoded result - foreach (var coordinate in coordinates) - { - int latitude = GetIntegerRepresentation(coordinate.Latitude); - int longitude = GetIntegerRepresentation(coordinate.Longitude); - - sb.Append(GetEncodedCharacters(latitude - previousLatitude).ToArray()); - sb.Append(GetEncodedCharacters(longitude - previousLongitude).ToArray()); - - previousLatitude = latitude; - previousLongitude = longitude; - } - - var result = sb.ToString(); - - _pool.Return(sb); - - return result; - } - - /// - /// Method performs coordinates validation. Throws exception, if invalid coordinate is found - /// - /// Coordinates to validate - /// If one or more coordinate is out of range -or- invalid - private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) - { - // Selecting invalid coordinates - var invalidCoordinates = coordinates - .Where(c => !CoordinateValidator.IsValid(c)); - - // If any invalid coordinates exists throw an aggregate exception with inner argument out of range exception - if (invalidCoordinates.Any()) - { - throw new AggregateException( - ExceptionMessageResource.AggregateExceptionCoordinatesAreInvalidErrorMessage, - invalidCoordinates - .Select(c => - new ArgumentOutOfRangeException( - string.Format( - ExceptionMessageResource.ArgumentExceptionCoordinateIsOutOfRangeErrorMessageFormat, - c.Latitude, - c.Longitude - ) - ) - ) - ); - } - } - - /// - /// - /// - /// Rounded integer representation of precise double value - /// Returns value with specific precision. See - private static double GetDoubleRepresentation(int value) - { - return Convert.ToDouble(value) / Constants.Precision; - } - - /// - /// Method converts value to polyline encoded characters - /// - /// Difference between current and previous latitude or longitude value - private static IEnumerable GetEncodedCharacters(int value) - { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) - { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } - - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - /// - /// Method - /// - /// Precise double representation - /// - private static int GetIntegerRepresentation(double value) - { - return (int)Math.Round(value * Constants.Precision); - } - - /// - /// Tries to calculate next integer representation of encoded polyline part - /// - /// The - /// The - /// The - /// The - private static bool TryCalculateNext(char[] polyline, ref int index, ref int value) - { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; - - - do - { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - #endregion - } -} diff --git a/src/Validation/CoordinateValidator.cs b/src/Validation/CoordinateValidator.cs deleted file mode 100644 index f0cd2b69..00000000 --- a/src/Validation/CoordinateValidator.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace DropoutCoder.PolylineAlgorithm.Validation -{ - /// - /// Performs coordinate validation - /// - public static class CoordinateValidator - { - #region Methods - - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) - { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - /// - /// Performs latitude validation - /// - /// Latitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) - { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - /// - /// Performs longitude validation - /// - /// Longitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) - { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - - #endregion - } -} diff --git a/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj b/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj new file mode 100644 index 00000000..23765838 --- /dev/null +++ b/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj @@ -0,0 +1,24 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + diff --git a/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs b/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs new file mode 100644 index 00000000..4d9672a9 --- /dev/null +++ b/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs @@ -0,0 +1,6 @@ +// +// Copyright (c) Petr Šrámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +global using Microsoft.VisualStudio.TestTools.UnitTesting; \ No newline at end of file diff --git a/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs b/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs new file mode 100644 index 00000000..9f5cd783 --- /dev/null +++ b/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs @@ -0,0 +1,52 @@ +// +// Copyright (c) Petr Šrámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests +{ + using Microsoft.Extensions.DependencyInjection; + + [TestClass] + public class ServiceCollectionExtensionsTests + { + internal static IServiceCollection Services { get; private set; } + + [ClassInitialize] + public static void Initialize(TestContext context) + { + Services = new ServiceCollection() + .AddDefaultPolylineEncoder(); + } + + [TestMethod] + public void AddDefaultCoordinateValidatorEncoderTest() + { + // Arrange + var provider = Services + .BuildServiceProvider(); + + // Act + var encoder = provider + .GetRequiredService>(); + + // Assert + Assert.IsInstanceOfType>(encoder); + } + + [TestMethod] + public void AddDefaultPolylineEncoderTest() + { + // Arrange + var provider = Services + .BuildServiceProvider(); + + // Act + var encoder = provider + .GetRequiredService>(); + + // Assert + Assert.IsInstanceOfType>(encoder); + } + } +} \ No newline at end of file diff --git a/tests/DropoutCoder.PolylineAlgorithm.Tests/CoordinateValidatorTest.cs b/tests/DropoutCoder.PolylineAlgorithm.Tests/CoordinateValidatorTest.cs new file mode 100644 index 00000000..8a7d7cfa --- /dev/null +++ b/tests/DropoutCoder.PolylineAlgorithm.Tests/CoordinateValidatorTest.cs @@ -0,0 +1,65 @@ +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace DropoutCoder.PolylineAlgorithm.Tests +{ + /// + /// Defines the + /// + [TestClass] + [TestCategory(nameof(DefaultCoordinateValidator))] + public class CoordinateValidatorTest + { + internal static DefaultCoordinateValidator Validator { get; private set; } + + [ClassInitialize] + public static void Initialize(TestContext context) + { + Validator = new DefaultCoordinateValidator(); + } + + #region Methods + + /// + /// The IsValid_InvalidInput + /// + [TestMethod] + public void IsValid_InvalidInput_IsFalse() + { + // Act + var invalidCoordinateCollection = Defaults.Coordinate.Invalid; + + foreach (var item in invalidCoordinateCollection) + { + // Arrange + var result = Validator.IsValid(item); + + // Assert + Assert.IsFalse(result); + } + } + + /// + /// The IsValid_ValidInput + /// + [TestMethod] + public void IsValid_ValidInput_IsTrue() + { + // Act + var validCoordinateCollection = Defaults.Coordinate.Valid; + + foreach (var item in validCoordinateCollection) + { + // Arrange + var result = Validator.IsValid(item); + + // Assert + Assert.IsTrue(result); + } + } + + #endregion + } +} diff --git a/tests/Defaults.cs b/tests/DropoutCoder.PolylineAlgorithm.Tests/Defaults.cs similarity index 100% rename from tests/Defaults.cs rename to tests/DropoutCoder.PolylineAlgorithm.Tests/Defaults.cs diff --git a/tests/DropoutCoder.PolylineAlgorithm.Tests.csproj b/tests/DropoutCoder.PolylineAlgorithm.Tests/DropoutCoder.PolylineAlgorithm.Tests.csproj similarity index 84% rename from tests/DropoutCoder.PolylineAlgorithm.Tests.csproj rename to tests/DropoutCoder.PolylineAlgorithm.Tests/DropoutCoder.PolylineAlgorithm.Tests.csproj index eba33c6a..5207a873 100644 --- a/tests/DropoutCoder.PolylineAlgorithm.Tests.csproj +++ b/tests/DropoutCoder.PolylineAlgorithm.Tests/DropoutCoder.PolylineAlgorithm.Tests.csproj @@ -17,7 +17,7 @@ - + \ No newline at end of file diff --git a/tests/DropoutCoder.PolylineAlgorithm.Tests/GlobalUsings.cs b/tests/DropoutCoder.PolylineAlgorithm.Tests/GlobalUsings.cs new file mode 100644 index 00000000..2b506c25 --- /dev/null +++ b/tests/DropoutCoder.PolylineAlgorithm.Tests/GlobalUsings.cs @@ -0,0 +1,9 @@ +// +// Copyright (c) Petr Šrámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +global using Microsoft.VisualStudio.TestTools.UnitTesting; +global using System; +global using System.Collections.Generic; +global using System.Linq; \ No newline at end of file diff --git a/tests/PolylineAlgorithmTest.cs b/tests/DropoutCoder.PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs similarity index 87% rename from tests/PolylineAlgorithmTest.cs rename to tests/DropoutCoder.PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs index bb1bbce8..188b537e 100644 --- a/tests/PolylineAlgorithmTest.cs +++ b/tests/DropoutCoder.PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs @@ -5,12 +5,6 @@ namespace DropoutCoder.PolylineAlgorithm.Tests { - using DropoutCoder.PolylineAlgorithm; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using System; - using System.Collections.Generic; - using System.Linq; - /// /// Defines the /// @@ -18,6 +12,14 @@ namespace DropoutCoder.PolylineAlgorithm.Tests [TestCategory(nameof(PolylineAlgorithm))] public class PolylineAlgorithmTest { + internal static DefaultPolylineEncoder Encoder { get; private set; } + + [ClassInitialize] + public static void Initialize(TestContext context) + { + Encoder = new DefaultPolylineEncoder(new DefaultCoordinateValidator()); + } + #region Methods /// @@ -33,7 +35,7 @@ public void Decode_EmptyInput_ThrowsException() // Act void DecodeEmptyPolylineCharArray() { - PolylineAlgorithm.Decode(emptyPolylineCharArray).ToArray(); + Encoder.Decode(emptyPolylineCharArray).ToArray(); } // Assert @@ -53,7 +55,7 @@ public void Decode_InvalidInput_ThrowsException() // Act void DecodeInvalidPolylineCharArray() { - PolylineAlgorithm.Decode(invalidPolylineCharrArray).ToArray(); + Encoder.Decode(invalidPolylineCharrArray).ToArray(); } // Assert @@ -73,7 +75,7 @@ public void Decode_NullInput_ThrowsException() // Act void DecodeNullPolylineCharArray() { - PolylineAlgorithm.Decode(nullPolylineCharArray).ToArray(); + Encoder.Decode(nullPolylineCharArray).ToArray(); } // Assert @@ -91,7 +93,7 @@ public void Decode_ValidInput_AreEquivalent() var validPolylineCharArray = Defaults.Polyline.Valid.ToCharArray(); // Act - var result = PolylineAlgorithm.Decode(validPolylineCharArray); + var result = Encoder.Decode(validPolylineCharArray); // Assert CollectionAssert.AreEquivalent(Defaults.Coordinate.Valid.ToList(), result.ToList()); @@ -110,7 +112,7 @@ public void Encode_EmptyInput_ThrowsException() // Act void EncodeEmptyCoordinates() { - PolylineAlgorithm.Encode(emptyCoordinates); + Encoder.Encode(emptyCoordinates); } // Assert @@ -129,7 +131,7 @@ public void Encode_InvalidInput_ThrowsException() // Act void EncodeInvalidCoordinates() { - PolylineAlgorithm.Encode(invalidCoordinates); + Encoder.Encode(invalidCoordinates); } // Assert @@ -149,7 +151,7 @@ public void Encode_NullInput_ThrowsException() // Act void EncodeNullCoordinates() { - PolylineAlgorithm.Encode(nullCoordinates); + Encoder.Encode(nullCoordinates); } // Assert @@ -166,7 +168,7 @@ public void Encode_ValidInput_AreEqual() var validCoordinates = Defaults.Coordinate.Valid; // Act - var result = PolylineAlgorithm.Encode(validCoordinates); + var result = Encoder.Encode(validCoordinates); // Assert Assert.AreEqual(Defaults.Polyline.Valid, result); diff --git a/tests/Properties/AssemblyInfo.cs b/tests/DropoutCoder.PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs similarity index 100% rename from tests/Properties/AssemblyInfo.cs rename to tests/DropoutCoder.PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Encoding/PolylineEncodingBaseTest.cs b/tests/Encoding/PolylineEncodingBaseTest.cs deleted file mode 100644 index 94993c83..00000000 --- a/tests/Encoding/PolylineEncodingBaseTest.cs +++ /dev/null @@ -1,196 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace DropoutCoder.PolylineAlgorithm.Tests.Encoding -{ - using DropoutCoder.PolylineAlgorithm.Encoding; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using System; - using System.Collections.Generic; - using System.Linq; - - /// - /// Defines the - /// - [TestClass] - [TestCategory(nameof(PolylineEncodingBase<(double latitude, double longitude)>))] - public class PolylineEncodingBaseTest : PolylineEncodingBase<(double latitude, double longitude)> - { - #region Methods - - /// - /// The Decode_NullInput - /// - [TestMethod] - public void Decode_NullInput_ThrowsException() - { - // Arrange - var nullPolylineString = (string)null; - - // Act - void DecodeNullPolylineString() - { - this.Decode(nullPolylineString).ToArray(); - } - - // Assert - Assert.ThrowsException(() => DecodeNullPolylineString()); - } - - /// - /// The Decode_EmptyInput - /// - [TestMethod] - public void Decode_EmptyInput_ThrowsException() - { - // Arrange - var emptyPolylineString = Defaults.Polyline.Empty; - - // Act - void DecodeEmptyPolylineString() - { - this.Decode(emptyPolylineString).ToArray(); - } - - // Assert - Assert.ThrowsException(() => DecodeEmptyPolylineString()); - } - - /// - /// The Decode_InvalidInput - /// - [TestMethod] - public void Decode_InvalidInput_ThrowsException() - { - // Arrange - var invalidPolylineString = Defaults.Polyline.Invalid; - - // Act - void DecodeInvalidPolylineString() - { - this.Decode(Defaults.Polyline.Invalid).ToArray(); - } - - // Assert - Assert.ThrowsException(() => DecodeInvalidPolylineString()); - } - - /// - /// The Decode_ValidInput - /// - [TestMethod] - public void Decode_ValidInput_AreEquivalent() - { - // Arrange - var validPolylineString = Defaults.Polyline.Valid; - - // Act - var result = this.Decode(validPolylineString).ToArray(); - - // Assert - CollectionAssert.AreEquivalent(Defaults.Coordinate.Valid.ToList(), result.ToList()); - } - - /// - /// The Encode_NullInput - /// - [TestMethod] - public void Encode_NullInput_ThrowsException() - { - // Arrange - var nullCoordinates = (IEnumerable<(double, double)>)null; - - // Act - void EncodeNullCoordinateCollection() - { - this.Encode(nullCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeNullCoordinateCollection()); - } - - /// - /// The Encode_EmptyInput - /// - [TestMethod] - public void Encode_EmptyInput_ThrowsException() - { - // Arrange - var emptyCoordinates = Defaults.Coordinate.Empty; - - // Act - void EncodeEmptyCoordinateCollection() - { - this.Encode(emptyCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeEmptyCoordinateCollection()); - } - - /// - /// The Encode_InvalidInput - /// - [TestMethod] - public void Encode_InvalidInput_ThrowsException() - { - // Arrange - var invalidCoordinates = Defaults.Coordinate.Invalid; - - // Act - void EncodeInvalidCoordinateCollection() - { - this.Encode(invalidCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeInvalidCoordinateCollection()); - } - - /// - /// The Encode_ValidInput - /// - [TestMethod] - public void Encode_ValidInput_AreEqual() - { - // Arrange - var validCoordinateCollection = Defaults.Coordinate.Valid; - - // Act - var result = this.Encode(validCoordinateCollection); - - // Assert - Assert.AreEqual(Defaults.Polyline.Valid, result); - } - - #region Overriden methods - - /// - /// The CreateResult - /// - /// The - /// The - /// The - protected override (double latitude, double longitude) CreateResult(double latitude, double longitude) - { - return (latitude, longitude); - } - - /// - /// The GetCoordinate - /// - /// The - /// The - protected override (double Latitude, double Longitude) GetCoordinate((double latitude, double longitude) source) - { - return source; - } - - #endregion - - #endregion - } -} diff --git a/tests/Encoding/PolylineEncodingTest.cs b/tests/Encoding/PolylineEncodingTest.cs deleted file mode 100644 index d7fdf05f..00000000 --- a/tests/Encoding/PolylineEncodingTest.cs +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace DropoutCoder.PolylineAlgorithm.Tests.Encoding -{ - using DropoutCoder.PolylineAlgorithm.Encoding; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using System.Linq; - - /// - /// Defines the - /// - [TestClass] - [TestCategory(nameof(PolylineEncoding))] - public class PolylineEncodingTest : PolylineEncoding - { - #region Methods - - /// - /// The CreateResult_AreEqual - /// - [TestMethod] - public void CreateResult_AreEqual() - { - // Arrange - var validCoordinate = Defaults.Coordinate.Valid.First(); - - // Act - var result = this.CreateResult(validCoordinate.Latitude, validCoordinate.Longitude); - - // Assert - Assert.AreEqual(validCoordinate, result); - } - - /// - /// The GetCoordinate_AreEqual - /// - [TestMethod] - public void GetCoordinate_AreEqual() - { - // Arrange - var validCoordinate = Defaults.Coordinate.Valid.First(); - - // Act - var result = this.GetCoordinate(validCoordinate); - - // Assert - Assert.AreEqual(validCoordinate, result); - } - - #endregion - } -} diff --git a/tests/Validation/CoordinateValidatorTest.cs b/tests/Validation/CoordinateValidatorTest.cs deleted file mode 100644 index 1d3f6540..00000000 --- a/tests/Validation/CoordinateValidatorTest.cs +++ /dev/null @@ -1,136 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace DropoutCoder.PolylineAlgorithm.Tests.Validation -{ - using DropoutCoder.PolylineAlgorithm.Validation; - using Microsoft.VisualStudio.TestTools.UnitTesting; - - /// - /// Defines the - /// - [TestClass] - [TestCategory(nameof(CoordinateValidator))] - public class CoordinateValidatorTest - { - #region Methods - - /// - /// The IsValid_InvalidInput - /// - [TestMethod] - public void IsValid_InvalidInput_IsFalse() - { - // Act - var invalidCoordinateCollection = Defaults.Coordinate.Invalid; - - foreach (var item in invalidCoordinateCollection) - { - // Arrange - var result = CoordinateValidator.IsValid(item); - - // Assert - Assert.IsFalse(result); - } - } - - /// - /// The IsValid_ValidInput - /// - [TestMethod] - public void IsValid_ValidInput_IsTrue() - { - // Act - var validCoordinateCollection = Defaults.Coordinate.Valid; - - foreach (var item in validCoordinateCollection) - { - // Arrange - var result = CoordinateValidator.IsValid(item); - - // Assert - Assert.IsTrue(result); - } - } - - /// - /// The IsValidLatitude_InvalidInput - /// - [TestMethod] - public void IsValidLatitude_InvalidInput_IsFalse() - { - // Act - var invalidCoordinateCollection = Defaults.Coordinate.Invalid; - - foreach (var item in invalidCoordinateCollection) - { - // Act - var result = CoordinateValidator.IsValidLatitude(item.Latitude); - - // Arrange - Assert.IsFalse(result); - } - } - - /// - /// The IsValidLatitude_ValidInput - /// - [TestMethod] - public void IsValidLatitude_ValidInput_IsTrue() - { - // Arrange - var validCoordinateCollection = Defaults.Coordinate.Valid; - - foreach ((double Latitude, double Longitude) in validCoordinateCollection) - { - // Act - var result = CoordinateValidator.IsValidLatitude(Latitude); - - // Assert - Assert.IsTrue(result); - } - } - - /// - /// The IsValidLongitude_InvalidInput - /// - [TestMethod] - public void IsValidLongitude_InvalidInput_IsFalse() - { - // Arrange - var invalidCoordinateCollection = Defaults.Coordinate.Invalid; - - foreach (var item in invalidCoordinateCollection) - { - // Act - var result = CoordinateValidator.IsValidLongitude(item.Longitude); - - // Assert - Assert.IsFalse(result); - } - } - - /// - /// The IsValidLongitude_ValidInput - /// - [TestMethod] - public void IsValidLongitude_ValidInput_IsTrue() - { - // Arrange - var validCoordinateCollection = Defaults.Coordinate.Valid; - - foreach (var item in validCoordinateCollection) - { - // Act - var result = CoordinateValidator.IsValidLongitude(item.Longitude); - - // Assert - Assert.IsTrue(result); - } - } - - #endregion - } -} From b53bffeed32a2de6c71ba8f827a84d09203be0ea Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Tue, 2 Jan 2024 19:11:01 +0100 Subject: [PATCH 004/352] fixed coordinate validation not throwing expected exception --- .../ExceptionMessageResource.Designer.cs | 4 ++-- .../ExceptionMessageResource.resx | 2 +- src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs | 6 ++++-- .../PolylineAlgorithmTest.cs | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.Designer.cs b/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.Designer.cs index 63d7a666..6832307d 100644 --- a/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.Designer.cs +++ b/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.Designer.cs @@ -19,7 +19,7 @@ namespace DropoutCoder.PolylineAlgorithm { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class ExceptionMessageResource { @@ -79,7 +79,7 @@ internal static string ArgumentCannotBeNullOrEmpty { } /// - /// Looks up a localized string similar to Latitude: {0}, Longitude: {1}) is invalid. Latitude must be in range between - 90 and +90. Longitude must be in range between -180 and +180.. + /// Looks up a localized string similar to Latitude must be in range between - 90 and +90. Longitude must be in range between -180 and +180.. /// internal static string ArgumentExceptionCoordinateIsOutOfRangeErrorMessageFormat { get { diff --git a/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.resx b/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.resx index 24b0415f..a539053a 100644 --- a/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.resx +++ b/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.resx @@ -124,7 +124,7 @@ Argument cannot be null -or- empty char array. - Latitude: {0}, Longitude: {1}) is invalid. Latitude must be in range between - 90 and +90. Longitude must be in range between -180 and +180. + Latitude must be in range between - 90 and +90. Longitude must be in range between -180 and +180. Polyline is malformed. diff --git a/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs b/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs index 622f0816..bdfd7758 100644 --- a/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs +++ b/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs @@ -108,7 +108,7 @@ public string Encode(IEnumerable collection) // Validate collection of coordinates if (!TryValidate(collection, out var invalid)) { - throw new ArgumentException(ExceptionMessageResource.AggregateExceptionCoordinatesAreInvalidErrorMessage, nameof(collection)); + throw new ArgumentOutOfRangeException(nameof(collection), ExceptionMessageResource.ArgumentExceptionCoordinateIsOutOfRangeErrorMessageFormat); } // Initializing local variables @@ -135,6 +135,7 @@ public string Encode(IEnumerable collection) return result; + #region Local functions bool TryValidate(IEnumerable collection, out ICollection validationErrors) { validationErrors = new List(); @@ -171,7 +172,8 @@ IEnumerable GetSequence(int value) } yield return (char)(rem + Constants.ASCII.QuestionMark); - } + } + #endregion } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/tests/DropoutCoder.PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs b/tests/DropoutCoder.PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs index 188b537e..e248cf5d 100644 --- a/tests/DropoutCoder.PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs +++ b/tests/DropoutCoder.PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs @@ -135,7 +135,7 @@ void EncodeInvalidCoordinates() } // Assert - Assert.ThrowsException(() => EncodeInvalidCoordinates()); + Assert.ThrowsException(() => EncodeInvalidCoordinates()); } /// From 52a2d02079fbe55766fb0311ea4d93e269d48312 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Tue, 2 Jan 2024 19:21:49 +0100 Subject: [PATCH 005/352] updated nuget packages --- ...Coder.PolylineAlgorithm.DependencyInjection.Tests.csproj | 6 +++--- .../DropoutCoder.PolylineAlgorithm.Tests.csproj | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj b/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj index 23765838..2168f981 100644 --- a/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj +++ b/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj @@ -11,9 +11,9 @@ - - - + + + diff --git a/tests/DropoutCoder.PolylineAlgorithm.Tests/DropoutCoder.PolylineAlgorithm.Tests.csproj b/tests/DropoutCoder.PolylineAlgorithm.Tests/DropoutCoder.PolylineAlgorithm.Tests.csproj index 5207a873..a64b9d65 100644 --- a/tests/DropoutCoder.PolylineAlgorithm.Tests/DropoutCoder.PolylineAlgorithm.Tests.csproj +++ b/tests/DropoutCoder.PolylineAlgorithm.Tests/DropoutCoder.PolylineAlgorithm.Tests.csproj @@ -10,9 +10,9 @@ - - - + + + From 0ced80a1735fb68acab469a1ba6bdd46d3de29c4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 3 Jan 2024 17:36:45 +0100 Subject: [PATCH 006/352] refactored implementation, updated benchmarks, updated tests --- .../PolylineEncodingBenchmark.cs | 4 +- .../DecodePerformanceBenchmark.cs | 4 ++ .../EncodePerformanceBenchmark.cs | 7 ++- .../ServiceCollectionExtensions.cs | 13 +--- .../CoordinateValidationException.cs | 14 +++++ .../DefaultPolylineEncoder.cs | 38 ------------ .../ExceptionMessageResource.Designer.cs | 6 +- .../ExceptionMessageResource.resx | 4 +- .../IPolylineEncoder.cs | 6 +- .../Internal/Constants.cs | 10 ---- .../CoordinateValidator.cs} | 12 +--- .../PolylineEncoder.cs | 60 +++++++------------ .../ServiceCollectionExtensionsTests.cs | 21 +------ .../CoordinateValidatorTest.cs | 10 ++-- .../PolylineAlgorithmTest.cs | 6 +- 15 files changed, 73 insertions(+), 142 deletions(-) create mode 100644 src/DropoutCoder.PolylineAlgorithm/CoordinateValidationException.cs delete mode 100644 src/DropoutCoder.PolylineAlgorithm/DefaultPolylineEncoder.cs rename src/DropoutCoder.PolylineAlgorithm/{DefaultCoordinateValidator.cs => Internal/CoordinateValidator.cs} (67%) diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs index 5dcaa08d..7d7c6d7c 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs @@ -20,14 +20,14 @@ public class PolylineEncodingBenchmark public IEnumerable<(double, double)> Coordinates; - internal DefaultPolylineEncoder Encoder { get; private set; } + internal PolylineEncoder Encoder { get; private set; } public char[] Polyline; [GlobalSetup] public void Setup() { - Encoder = new DefaultPolylineEncoder(new DefaultCoordinateValidator()); + Encoder = new PolylineEncoder(); Coordinates = new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }; Polyline = "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB".ToCharArray(); } diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs index acd4ba8f..b624f93a 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs @@ -13,6 +13,10 @@ namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks public class DecodePerformanceBenchmark { private Consumer _consumer = new Consumer(); + + [Params(10_000)] + public int N { get; set; } + public static IEnumerable<(int, char[])> Polylines() { yield return (1, "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI".ToCharArray()); diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs index 1d441be6..4576344a 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs @@ -16,6 +16,9 @@ public class EncodePerformanceBenchmark { private Consumer _consumer = new Consumer(); + [Params(10_000)] + public int N { get; set; } + public IEnumerable<(int, IEnumerable<(double, double)>)> Coordinates() { yield return (1, new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) }); @@ -48,7 +51,7 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo int lastLatitude = 0; int lastLongitude = 0; - var sb = new StringBuilder(); + var sb = new StringBuilder(coordinates.Count() * 5); foreach (var coordinate in coordinates) { @@ -220,7 +223,7 @@ public static bool IsValidLongitude(double longitude) private class V3 { - private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, int.MaxValue); + private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); public static string Encode(IEnumerable<(double Latitude, double Longitude)> collection) { diff --git a/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs b/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs index f2d9c4c5..388cb02f 100644 --- a/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs @@ -9,19 +9,10 @@ namespace DropoutCoder.PolylineAlgorithm.DependencyInjection public static class ServiceCollectionExtensions { - public static IServiceCollection AddDefaultPolylineEncoder(this IServiceCollection services) + public static IServiceCollection AddPolylineEncoder(this IServiceCollection services) { return services - .AddPolylineEncoder(); - } - - public static IServiceCollection AddPolylineEncoder(this IServiceCollection services) - where TEncoder : class, IPolylineEncoder - where TValidator : class, ICoordinateValidator - { - return services - .AddSingleton, TValidator>() - .AddSingleton, TEncoder>(); + .AddSingleton(); } } } diff --git a/src/DropoutCoder.PolylineAlgorithm/CoordinateValidationException.cs b/src/DropoutCoder.PolylineAlgorithm/CoordinateValidationException.cs new file mode 100644 index 00000000..19c9d132 --- /dev/null +++ b/src/DropoutCoder.PolylineAlgorithm/CoordinateValidationException.cs @@ -0,0 +1,14 @@ +namespace DropoutCoder.PolylineAlgorithm +{ + using System; + + public class CoordinateValidationException : Exception + { + public CoordinateValidationException(double latitude, double longitude) + : base(string.Format(ExceptionMessageResource.CoordinateValidationExceptionCoordinateIsOutOfRangeErrorMessageFormat, latitude, longitude)) { } + + public double Latitude { get; } + + public double Longitude { get; } + } +} diff --git a/src/DropoutCoder.PolylineAlgorithm/DefaultPolylineEncoder.cs b/src/DropoutCoder.PolylineAlgorithm/DefaultPolylineEncoder.cs deleted file mode 100644 index 79bd9775..00000000 --- a/src/DropoutCoder.PolylineAlgorithm/DefaultPolylineEncoder.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace DropoutCoder.PolylineAlgorithm -{ - using System.Runtime.CompilerServices; - - public sealed class DefaultPolylineEncoder : PolylineEncoder<(double Latitude, double Longitude)> - { - public DefaultPolylineEncoder(ICoordinateValidator<(double Latitude, double Longitude)> validator) - : base(validator) { } - - /// - /// Method creates result from passed latitude and longitude arguments - /// - /// Latitude value - /// Longitude value - /// Returns created instance of - [MethodImpl(MethodImplOptions.AggressiveInlining)] - protected override (double Latitude, double Longitude) CreateResult(double latitude, double longitude) - { - return (latitude, longitude); - } - - /// - /// Method creates - /// - /// The - /// Returns created coordinate - [MethodImpl(MethodImplOptions.AggressiveInlining)] - protected override (double Latitude, double Longitude) GetCoordinate((double Latitude, double Longitude) value) - { - return value; - } - } -} diff --git a/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.Designer.cs b/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.Designer.cs index 6832307d..0b13459c 100644 --- a/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.Designer.cs +++ b/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.Designer.cs @@ -79,11 +79,11 @@ internal static string ArgumentCannotBeNullOrEmpty { } /// - /// Looks up a localized string similar to Latitude must be in range between - 90 and +90. Longitude must be in range between -180 and +180.. + /// Looks up a localized string similar to Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.. /// - internal static string ArgumentExceptionCoordinateIsOutOfRangeErrorMessageFormat { + internal static string CoordinateValidationExceptionCoordinateIsOutOfRangeErrorMessageFormat { get { - return ResourceManager.GetString("ArgumentExceptionCoordinateIsOutOfRangeErrorMessageFormat", resourceCulture); + return ResourceManager.GetString("CoordinateValidationExceptionCoordinateIsOutOfRangeErrorMessageFormat", resourceCulture); } } diff --git a/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.resx b/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.resx index a539053a..04001b03 100644 --- a/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.resx +++ b/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.resx @@ -123,8 +123,8 @@ Argument cannot be null -or- empty char array. - - Latitude must be in range between - 90 and +90. Longitude must be in range between -180 and +180. + + Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180. Polyline is malformed. diff --git a/src/DropoutCoder.PolylineAlgorithm/IPolylineEncoder.cs b/src/DropoutCoder.PolylineAlgorithm/IPolylineEncoder.cs index 31b52872..ebe22851 100644 --- a/src/DropoutCoder.PolylineAlgorithm/IPolylineEncoder.cs +++ b/src/DropoutCoder.PolylineAlgorithm/IPolylineEncoder.cs @@ -11,7 +11,7 @@ namespace DropoutCoder.PolylineAlgorithm /// Defines base interface for all polyline encodings /// /// Desired type used to decode to and encode from - public interface IPolylineEncoder + public interface IPolylineEncoder { #region Methods @@ -20,14 +20,14 @@ public interface IPolylineEncoder /// /// Encoded coordinates /// The - IEnumerable Decode(char[] source); + IEnumerable<(double Latitude, double Longitude)> Decode(char[] value); /// /// Method performs encoding from generic type to polyline encoded /// /// Coordinates to encode /// Polyline encoded result - string Encode(IEnumerable source); + string Encode(IEnumerable<(double Latitude, double Longitude)> collection); #endregion } diff --git a/src/DropoutCoder.PolylineAlgorithm/Internal/Constants.cs b/src/DropoutCoder.PolylineAlgorithm/Internal/Constants.cs index 6b498cce..9c118940 100644 --- a/src/DropoutCoder.PolylineAlgorithm/Internal/Constants.cs +++ b/src/DropoutCoder.PolylineAlgorithm/Internal/Constants.cs @@ -66,16 +66,6 @@ internal static class Coordinate /// public const int MaxLongitude = 180; - /// - /// Defines the minimum value for latitude - /// - public const int MinLatitude = -MaxLatitude; - - /// - /// Defines the minimum value for longitude - /// - public const int MinLongitude = -MaxLongitude; - #endregion } } diff --git a/src/DropoutCoder.PolylineAlgorithm/DefaultCoordinateValidator.cs b/src/DropoutCoder.PolylineAlgorithm/Internal/CoordinateValidator.cs similarity index 67% rename from src/DropoutCoder.PolylineAlgorithm/DefaultCoordinateValidator.cs rename to src/DropoutCoder.PolylineAlgorithm/Internal/CoordinateValidator.cs index 6c828a98..32c3bb0e 100644 --- a/src/DropoutCoder.PolylineAlgorithm/DefaultCoordinateValidator.cs +++ b/src/DropoutCoder.PolylineAlgorithm/Internal/CoordinateValidator.cs @@ -1,19 +1,13 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -using DropoutCoder.PolylineAlgorithm.Internal; - -namespace DropoutCoder.PolylineAlgorithm +namespace DropoutCoder.PolylineAlgorithm.Internal { using System; using System.Runtime.CompilerServices; + /// /// Performs coordinate validation /// - public class DefaultCoordinateValidator : ICoordinateValidator<(double Latitude, double Longitude)> + internal class CoordinateValidator { #region Methods diff --git a/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs b/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs index bdfd7758..f524183a 100644 --- a/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs +++ b/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs @@ -6,27 +6,20 @@ namespace DropoutCoder.PolylineAlgorithm { using DropoutCoder.PolylineAlgorithm.Internal; + using Microsoft.Extensions.ObjectPool; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; - public abstract class PolylineEncoder : IPolylineEncoder + public sealed class PolylineEncoder : IPolylineEncoder { - private static Lazy _default = new Lazy(() => new DefaultPolylineEncoder(new DefaultCoordinateValidator())); - - public static IPolylineEncoder<(double Latitude, double Longitude)> Default => _default.Value; - - public ICoordinateValidator Validator { get; } - - public PolylineEncoder(ICoordinateValidator validator) - { - Validator = validator; - } + private readonly CoordinateValidator _validator = new CoordinateValidator(); + private readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public IEnumerable Decode(char[] polyline) + public IEnumerable<(double Latitude, double Longitude)> Decode(char[] polyline) { // Checking null and at least one character if (polyline == null || polyline.Length == 0) @@ -54,16 +47,15 @@ public IEnumerable Decode(char[] polyline) throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } - var coordinate = CreateResult(GetCoordinate(latitude), GetCoordinate(longitude)); + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - if (!Validator.IsValid(coordinate)) + if (!_validator.IsValid(coordinate)) { throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } yield return coordinate; - #region Local functions bool TryCalculateNext(char[] polyline, ref int index, ref int value) @@ -98,29 +90,27 @@ double GetCoordinate(int value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public string Encode(IEnumerable collection) + public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (collection == null || !collection.GetEnumerator().MoveNext()) + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(collection)); + throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(coordinates)); } // Validate collection of coordinates - if (!TryValidate(collection, out var invalid)) + if (!TryValidate(coordinates, out var exceptions)) { - throw new ArgumentOutOfRangeException(nameof(collection), ExceptionMessageResource.ArgumentExceptionCoordinateIsOutOfRangeErrorMessageFormat); + throw new AggregateException(exceptions); } // Initializing local variables int previousLatitude = 0; int previousLongitude = 0; - var sb = new StringBuilder(); + var sb = _pool.Get(); // Looping over coordinates and building encoded result - foreach (var item in collection) + foreach (var coordinate in coordinates) { - var coordinate = GetCoordinate(item); - int latitude = Round(coordinate.Latitude); int longitude = Round(coordinate.Longitude); @@ -133,22 +123,24 @@ public string Encode(IEnumerable collection) var result = sb.ToString(); + _pool.Return(sb); + return result; #region Local functions - bool TryValidate(IEnumerable collection, out ICollection validationErrors) + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) { - validationErrors = new List(); + exceptions = new List(collection.Count()); foreach (var item in collection) { - if (!Validator.IsValid(item)) + if (!_validator.IsValid(item)) { - validationErrors.Add(item); + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); } } - return !validationErrors.GetEnumerator().MoveNext(); + return !exceptions.GetEnumerator().MoveNext(); } int Round(double value) @@ -172,14 +164,8 @@ IEnumerable GetSequence(int value) } yield return (char)(rem + Constants.ASCII.QuestionMark); - } - #endregion + } } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - protected abstract T CreateResult(double latitude, double longitude); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - protected abstract (double Latitude, double Longitude) GetCoordinate(T value); + #endregion } } diff --git a/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs b/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs index 9f5cd783..941cf008 100644 --- a/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs +++ b/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs @@ -16,22 +16,7 @@ public class ServiceCollectionExtensionsTests public static void Initialize(TestContext context) { Services = new ServiceCollection() - .AddDefaultPolylineEncoder(); - } - - [TestMethod] - public void AddDefaultCoordinateValidatorEncoderTest() - { - // Arrange - var provider = Services - .BuildServiceProvider(); - - // Act - var encoder = provider - .GetRequiredService>(); - - // Assert - Assert.IsInstanceOfType>(encoder); + .AddPolylineEncoder(); } [TestMethod] @@ -43,10 +28,10 @@ public void AddDefaultPolylineEncoderTest() // Act var encoder = provider - .GetRequiredService>(); + .GetRequiredService(); // Assert - Assert.IsInstanceOfType>(encoder); + Assert.IsInstanceOfType(encoder); } } } \ No newline at end of file diff --git a/tests/DropoutCoder.PolylineAlgorithm.Tests/CoordinateValidatorTest.cs b/tests/DropoutCoder.PolylineAlgorithm.Tests/CoordinateValidatorTest.cs index 8a7d7cfa..cf977e42 100644 --- a/tests/DropoutCoder.PolylineAlgorithm.Tests/CoordinateValidatorTest.cs +++ b/tests/DropoutCoder.PolylineAlgorithm.Tests/CoordinateValidatorTest.cs @@ -5,19 +5,21 @@ namespace DropoutCoder.PolylineAlgorithm.Tests { + using DropoutCoder.PolylineAlgorithm.Internal; + /// /// Defines the /// [TestClass] - [TestCategory(nameof(DefaultCoordinateValidator))] - public class CoordinateValidatorTest + [TestCategory(nameof(CoordinateValidator))] + public class CoordinateValidatorTestCoordinate { - internal static DefaultCoordinateValidator Validator { get; private set; } + internal static CoordinateValidator Validator { get; private set; } [ClassInitialize] public static void Initialize(TestContext context) { - Validator = new DefaultCoordinateValidator(); + Validator = new CoordinateValidator(); } #region Methods diff --git a/tests/DropoutCoder.PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs b/tests/DropoutCoder.PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs index e248cf5d..c2c5e70a 100644 --- a/tests/DropoutCoder.PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs +++ b/tests/DropoutCoder.PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs @@ -12,12 +12,12 @@ namespace DropoutCoder.PolylineAlgorithm.Tests [TestCategory(nameof(PolylineAlgorithm))] public class PolylineAlgorithmTest { - internal static DefaultPolylineEncoder Encoder { get; private set; } + internal static PolylineEncoder Encoder { get; private set; } [ClassInitialize] public static void Initialize(TestContext context) { - Encoder = new DefaultPolylineEncoder(new DefaultCoordinateValidator()); + Encoder = new PolylineEncoder(); } #region Methods @@ -135,7 +135,7 @@ void EncodeInvalidCoordinates() } // Assert - Assert.ThrowsException(() => EncodeInvalidCoordinates()); + Assert.ThrowsException(() => EncodeInvalidCoordinates()); } /// From 55e78eba89a6a192d6ec6c757ac435a1ddc395f1 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 3 Jan 2024 17:40:36 +0100 Subject: [PATCH 007/352] updated nuget nuspec target --- nuget/DropoutCoder.PolylineAlgorithm.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nuget/DropoutCoder.PolylineAlgorithm.nuspec b/nuget/DropoutCoder.PolylineAlgorithm.nuspec index c3c66c81..84930295 100644 --- a/nuget/DropoutCoder.PolylineAlgorithm.nuspec +++ b/nuget/DropoutCoder.PolylineAlgorithm.nuspec @@ -14,6 +14,6 @@ $nugetprojecturl$ - + \ No newline at end of file From becf6e18a85e178021b217f1f7aadb18f5f6c26f Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 3 Jan 2024 17:43:26 +0100 Subject: [PATCH 008/352] added exptension project nuspec file --- DropoutCoder.PolylineAlgorithm.sln | 2 +- ...tCoder.PolylineAlgorithm.Extensions.nuspec | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 nuget/DropoutCoder.PolylineAlgorithm.Extensions.nuspec diff --git a/DropoutCoder.PolylineAlgorithm.sln b/DropoutCoder.PolylineAlgorithm.sln index ffaeb45b..38119837 100644 --- a/DropoutCoder.PolylineAlgorithm.sln +++ b/DropoutCoder.PolylineAlgorithm.sln @@ -25,7 +25,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgori EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm.DependencyInjection", "src\DropoutCoder.PolylineAlgorithm.DependencyInjection\DropoutCoder.PolylineAlgorithm.DependencyInjection.csproj", "{0F07B56B-6D9A-4410-BCAB-C6A460C1E44E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests", "tests\DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests\DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj", "{9DC1BAD9-60DD-414D-BE88-E181D887A267}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests", "tests\DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests\DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj", "{9DC1BAD9-60DD-414D-BE88-E181D887A267}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/nuget/DropoutCoder.PolylineAlgorithm.Extensions.nuspec b/nuget/DropoutCoder.PolylineAlgorithm.Extensions.nuspec new file mode 100644 index 00000000..84930295 --- /dev/null +++ b/nuget/DropoutCoder.PolylineAlgorithm.Extensions.nuspec @@ -0,0 +1,19 @@ + + + + $nugetid$ + $nugettitle$ + $nugetversion$ + $nugetauthors$ + $nugetowners$ + $nugetdescription$ + $nugetsummary$ + $nugetcopyright$ + $nugettags$ + $nugetlicenceurl$ + $nugetprojecturl$ + + + + + \ No newline at end of file From b3d1aea14fbb6a14535903d41c5fff30323236de Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 10 Jan 2024 10:43:31 +0100 Subject: [PATCH 009/352] just commit --- .../ICoordinateValidator.cs | 12 ------------ .../Internal/Constants.cs | 10 ++++++++++ .../Internal/CoordinateValidator.cs | 14 +++++++++++++- .../PolylineAlgorithm.cs | 6 ++++++ .../PolylineEncoder.cs | 15 ++++++--------- 5 files changed, 35 insertions(+), 22 deletions(-) delete mode 100644 src/DropoutCoder.PolylineAlgorithm/ICoordinateValidator.cs create mode 100644 src/DropoutCoder.PolylineAlgorithm/PolylineAlgorithm.cs diff --git a/src/DropoutCoder.PolylineAlgorithm/ICoordinateValidator.cs b/src/DropoutCoder.PolylineAlgorithm/ICoordinateValidator.cs deleted file mode 100644 index 2a6bf553..00000000 --- a/src/DropoutCoder.PolylineAlgorithm/ICoordinateValidator.cs +++ /dev/null @@ -1,12 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace DropoutCoder.PolylineAlgorithm -{ - public interface ICoordinateValidator - { - bool IsValid(T coordinate); - } -} diff --git a/src/DropoutCoder.PolylineAlgorithm/Internal/Constants.cs b/src/DropoutCoder.PolylineAlgorithm/Internal/Constants.cs index 9c118940..3193eb63 100644 --- a/src/DropoutCoder.PolylineAlgorithm/Internal/Constants.cs +++ b/src/DropoutCoder.PolylineAlgorithm/Internal/Constants.cs @@ -66,6 +66,16 @@ internal static class Coordinate /// public const int MaxLongitude = 180; + /// + /// Defines the maximum value for latitude + /// + public const int MinLatitude = -MaxLatitude; + + /// + /// Defines the maximum value for longitude + /// + public const int MinLongitude = -MaxLongitude; + #endregion } } diff --git a/src/DropoutCoder.PolylineAlgorithm/Internal/CoordinateValidator.cs b/src/DropoutCoder.PolylineAlgorithm/Internal/CoordinateValidator.cs index 32c3bb0e..6f8824d8 100644 --- a/src/DropoutCoder.PolylineAlgorithm/Internal/CoordinateValidator.cs +++ b/src/DropoutCoder.PolylineAlgorithm/Internal/CoordinateValidator.cs @@ -19,7 +19,19 @@ internal class CoordinateValidator [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsValid((double Latitude, double Longitude) coordinate) { - return Math.Abs(coordinate.Latitude) <= Constants.Coordinate.MaxLatitude && Math.Abs(coordinate.Longitude) <= Constants.Coordinate.MaxLongitude; + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsValidLatitude(double latitude) + { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsValidLongitude(double longitude) + { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } #endregion diff --git a/src/DropoutCoder.PolylineAlgorithm/PolylineAlgorithm.cs b/src/DropoutCoder.PolylineAlgorithm/PolylineAlgorithm.cs new file mode 100644 index 00000000..8b6cffb2 --- /dev/null +++ b/src/DropoutCoder.PolylineAlgorithm/PolylineAlgorithm.cs @@ -0,0 +1,6 @@ +namespace DropoutCoder.PolylineAlgorithm +{ + public static class PolylineAlgorithm + { + } +} diff --git a/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs b/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs index f524183a..f288bb7a 100644 --- a/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs +++ b/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs @@ -6,7 +6,6 @@ namespace DropoutCoder.PolylineAlgorithm { using DropoutCoder.PolylineAlgorithm.Internal; - using Microsoft.Extensions.ObjectPool; using System; using System.Collections.Generic; using System.Linq; @@ -16,7 +15,6 @@ namespace DropoutCoder.PolylineAlgorithm public sealed class PolylineEncoder : IPolylineEncoder { private readonly CoordinateValidator _validator = new CoordinateValidator(); - private readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); [MethodImpl(MethodImplOptions.AggressiveInlining)] public IEnumerable<(double Latitude, double Longitude)> Decode(char[] polyline) @@ -49,6 +47,7 @@ public sealed class PolylineEncoder : IPolylineEncoder var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + // Validating decoded coordinate. If not valid exception is thrown if (!_validator.IsValid(coordinate)) { throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); @@ -106,7 +105,7 @@ public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinate // Initializing local variables int previousLatitude = 0; int previousLongitude = 0; - var sb = _pool.Get(); + var sb = new StringBuilder(coordinates.Count() * 5); // Looping over coordinates and building encoded result foreach (var coordinate in coordinates) @@ -121,13 +120,10 @@ public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinate previousLongitude = longitude; } - var result = sb.ToString(); - - _pool.Return(sb); - - return result; + return sb.ToString(); #region Local functions + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) { exceptions = new List(collection.Count()); @@ -165,7 +161,8 @@ IEnumerable GetSequence(int value) yield return (char)(rem + Constants.ASCII.QuestionMark); } + + #endregion } - #endregion } } From 5de7c4df6d06e56d051d71331657c5fdafe3aab6 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 10 Jan 2024 10:57:07 +0100 Subject: [PATCH 010/352] removed regions --- src/Constants.cs | 12 --------- src/Encoding/IPolylineEncoding.cs | 8 ------ src/Encoding/PolylineEncoding.cs | 4 --- src/Encoding/PolylineEncodingBase.cs | 6 +---- src/PolylineAlgorithm.cs | 4 --- src/Validation/CoordinateValidator.cs | 4 --- tests/Defaults.cs | 28 ++++++++------------- tests/Encoding/PolylineEncodingBaseTest.cs | 4 --- tests/Encoding/PolylineEncodingTest.cs | 4 --- tests/PolylineAlgorithmTest.cs | 4 --- tests/Validation/CoordinateValidatorTest.cs | 4 --- 11 files changed, 11 insertions(+), 71 deletions(-) diff --git a/src/Constants.cs b/src/Constants.cs index b05a5029..8162089d 100644 --- a/src/Constants.cs +++ b/src/Constants.cs @@ -10,8 +10,6 @@ namespace DropoutCoder.PolylineAlgorithm /// internal static class Constants { - #region Constants - /// /// Defines the coordinate precision /// @@ -22,15 +20,11 @@ internal static class Constants /// public const int ShiftLength = 5; - #endregion - /// /// Defines ASCII characters constant values /// internal static class ASCII { - #region Constants - /// /// Defines the ASCII Question Mark /// @@ -45,8 +39,6 @@ internal static class ASCII /// Defines the ASCII Unit Separator /// public const int UnitSeparator = 31; - - #endregion } /// @@ -54,8 +46,6 @@ internal static class ASCII /// internal static class Coordinate { - #region Constants - /// /// Defines the maximum value for latitude /// @@ -75,8 +65,6 @@ internal static class Coordinate /// Defines the minimum value for longitude /// public const int MinLongitude = -MaxLongitude; - - #endregion } } } diff --git a/src/Encoding/IPolylineEncoding.cs b/src/Encoding/IPolylineEncoding.cs index 82348ac5..f03cd15e 100644 --- a/src/Encoding/IPolylineEncoding.cs +++ b/src/Encoding/IPolylineEncoding.cs @@ -7,16 +7,12 @@ namespace DropoutCoder.PolylineAlgorithm.Encoding { using System.Collections.Generic; - #region Interfaces - /// /// Defines base interface for all polyline encodings /// /// Desired type used to decode to and encode from public interface IPolylineEncoding { - #region Methods - /// /// Method performs decoding from polyline encoded to /// @@ -30,9 +26,5 @@ public interface IPolylineEncoding /// Coordinates to encode /// Polyline encoded result string Encode(IEnumerable source); - - #endregion } - - #endregion } diff --git a/src/Encoding/PolylineEncoding.cs b/src/Encoding/PolylineEncoding.cs index 058d56e5..357c4973 100644 --- a/src/Encoding/PolylineEncoding.cs +++ b/src/Encoding/PolylineEncoding.cs @@ -10,8 +10,6 @@ namespace DropoutCoder.PolylineAlgorithm.Encoding /// public class PolylineEncoding : PolylineEncodingBase<(double Latitude, double Longitude)> { - #region Methods - /// /// Method creates result from passed latitude and longitude arguments /// @@ -32,7 +30,5 @@ protected override (double Latitude, double Longitude) GetCoordinate((double Lat { return source; } - - #endregion } } diff --git a/src/Encoding/PolylineEncodingBase.cs b/src/Encoding/PolylineEncodingBase.cs index b3de4cfb..a07b7f24 100644 --- a/src/Encoding/PolylineEncodingBase.cs +++ b/src/Encoding/PolylineEncodingBase.cs @@ -15,8 +15,6 @@ namespace DropoutCoder.PolylineAlgorithm.Encoding /// public abstract class PolylineEncodingBase : IPolylineEncoding { - #region Methods - /// /// Method performs decode operation and coversion to desired type /// @@ -24,7 +22,7 @@ public abstract class PolylineEncodingBase : IPolylineEncoding /// The public IEnumerable Decode(string source) { - if (string.IsNullOrEmpty(source)) + if (string.IsNullOrWhiteSpace(source)) { throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(source)); } @@ -66,7 +64,5 @@ public string Encode(IEnumerable source) /// The /// The protected abstract (double Latitude, double Longitude) GetCoordinate(T source); - - #endregion } } diff --git a/src/PolylineAlgorithm.cs b/src/PolylineAlgorithm.cs index 1f700191..d5afccb8 100644 --- a/src/PolylineAlgorithm.cs +++ b/src/PolylineAlgorithm.cs @@ -19,8 +19,6 @@ public static class PolylineAlgorithm { private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); - #region Methods - /// /// Method decodes polyline encoded representation to coordinates. /// @@ -210,7 +208,5 @@ private static bool TryCalculateNext(char[] polyline, ref int index, ref int val return true; } - - #endregion } } diff --git a/src/Validation/CoordinateValidator.cs b/src/Validation/CoordinateValidator.cs index f0cd2b69..2ae19295 100644 --- a/src/Validation/CoordinateValidator.cs +++ b/src/Validation/CoordinateValidator.cs @@ -10,8 +10,6 @@ namespace DropoutCoder.PolylineAlgorithm.Validation /// public static class CoordinateValidator { - #region Methods - /// /// Performs coordinate validation /// @@ -41,7 +39,5 @@ public static bool IsValidLongitude(double longitude) { return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } - - #endregion } } diff --git a/tests/Defaults.cs b/tests/Defaults.cs index bc54f777..26d58866 100644 --- a/tests/Defaults.cs +++ b/tests/Defaults.cs @@ -19,8 +19,6 @@ public static class Defaults /// public static class Coordinate { - #region Fields - /// /// Defines empty range of coordinates. Equals to decoded /// @@ -30,23 +28,21 @@ public static class Coordinate /// Defines range of invalid coordinates. Equals to decoded /// public static readonly IEnumerable<(double Latitude, double Longitude)> Invalid = new[] { - (149.47383, 259.06250), - (-158.37407, 225.31250), - (152.99363, -220.93750), - (-144.49024, -274.37500) - }; + (149.47383, 259.06250), + (-158.37407, 225.31250), + (152.99363, -220.93750), + (-144.49024, -274.37500) + }; /// /// Defines range of valid coordinates. Equals to decoded /// public static readonly IEnumerable<(double Latitude, double Longitude)> Valid = new[] { - (49.47383, 59.06250), - (-58.37407, 25.31250), - (52.99363, -120.93750), - (-44.49024, -174.37500) - }; - - #endregion + (49.47383, 59.06250), + (-58.37407, 25.31250), + (52.99363, -120.93750), + (-44.49024, -174.37500) + }; } /// @@ -54,8 +50,6 @@ public static class Coordinate /// public static class Polyline { - #region Fields - /// /// Defines empty string of polyline encoded coordinates. Equals to encoded /// @@ -70,8 +64,6 @@ public static class Polyline /// Defines polyline encoded range of valid coordinates. Equals to encoded /// public static readonly string Valid = "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; - - #endregion } } } diff --git a/tests/Encoding/PolylineEncodingBaseTest.cs b/tests/Encoding/PolylineEncodingBaseTest.cs index 94993c83..fc695653 100644 --- a/tests/Encoding/PolylineEncodingBaseTest.cs +++ b/tests/Encoding/PolylineEncodingBaseTest.cs @@ -18,8 +18,6 @@ namespace DropoutCoder.PolylineAlgorithm.Tests.Encoding [TestCategory(nameof(PolylineEncodingBase<(double latitude, double longitude)>))] public class PolylineEncodingBaseTest : PolylineEncodingBase<(double latitude, double longitude)> { - #region Methods - /// /// The Decode_NullInput /// @@ -190,7 +188,5 @@ protected override (double Latitude, double Longitude) GetCoordinate((double lat } #endregion - - #endregion } } diff --git a/tests/Encoding/PolylineEncodingTest.cs b/tests/Encoding/PolylineEncodingTest.cs index d7fdf05f..697eb1a3 100644 --- a/tests/Encoding/PolylineEncodingTest.cs +++ b/tests/Encoding/PolylineEncodingTest.cs @@ -16,8 +16,6 @@ namespace DropoutCoder.PolylineAlgorithm.Tests.Encoding [TestCategory(nameof(PolylineEncoding))] public class PolylineEncodingTest : PolylineEncoding { - #region Methods - /// /// The CreateResult_AreEqual /// @@ -49,7 +47,5 @@ public void GetCoordinate_AreEqual() // Assert Assert.AreEqual(validCoordinate, result); } - - #endregion } } diff --git a/tests/PolylineAlgorithmTest.cs b/tests/PolylineAlgorithmTest.cs index bb1bbce8..317a6472 100644 --- a/tests/PolylineAlgorithmTest.cs +++ b/tests/PolylineAlgorithmTest.cs @@ -18,8 +18,6 @@ namespace DropoutCoder.PolylineAlgorithm.Tests [TestCategory(nameof(PolylineAlgorithm))] public class PolylineAlgorithmTest { - #region Methods - /// /// Method is testing method. Empty [] is passed as parameter. /// Expected result is . @@ -171,7 +169,5 @@ public void Encode_ValidInput_AreEqual() // Assert Assert.AreEqual(Defaults.Polyline.Valid, result); } - - #endregion } } diff --git a/tests/Validation/CoordinateValidatorTest.cs b/tests/Validation/CoordinateValidatorTest.cs index 1d3f6540..d8d0a404 100644 --- a/tests/Validation/CoordinateValidatorTest.cs +++ b/tests/Validation/CoordinateValidatorTest.cs @@ -15,8 +15,6 @@ namespace DropoutCoder.PolylineAlgorithm.Tests.Validation [TestCategory(nameof(CoordinateValidator))] public class CoordinateValidatorTest { - #region Methods - /// /// The IsValid_InvalidInput /// @@ -130,7 +128,5 @@ public void IsValidLongitude_ValidInput_IsTrue() Assert.IsTrue(result); } } - - #endregion } } From c41a00d08445040a8363a8ca953368e5c6290e52 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 10 Jan 2024 11:19:47 +0100 Subject: [PATCH 011/352] refactored polyline algorithm --- src/Encoding/PolylineEncodingBase.cs | 8 +- src/ExceptionMessageResource.Designer.cs | 8 +- src/ExceptionMessageResource.resx | 4 +- src/PolylineAlgorithm.cs | 179 ++++++++---------- .../CoordinateValidationException.cs | 27 +++ 5 files changed, 111 insertions(+), 115 deletions(-) create mode 100644 src/Validation/CoordinateValidationException.cs diff --git a/src/Encoding/PolylineEncodingBase.cs b/src/Encoding/PolylineEncodingBase.cs index a07b7f24..e59ef0c2 100644 --- a/src/Encoding/PolylineEncodingBase.cs +++ b/src/Encoding/PolylineEncodingBase.cs @@ -20,15 +20,13 @@ public abstract class PolylineEncodingBase : IPolylineEncoding /// /// The /// The - public IEnumerable Decode(string source) + public IEnumerable Decode(string polyline) { - if (string.IsNullOrWhiteSpace(source)) + if (string.IsNullOrWhiteSpace(polyline)) { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(source)); + throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(polyline)); } - char[] polyline = source.ToCharArray(); - return PolylineAlgorithm.Decode(polyline) .Select(c => CreateResult(c.Latitude, c.Longitude)); } diff --git a/src/ExceptionMessageResource.Designer.cs b/src/ExceptionMessageResource.Designer.cs index 63d7a666..0b13459c 100644 --- a/src/ExceptionMessageResource.Designer.cs +++ b/src/ExceptionMessageResource.Designer.cs @@ -19,7 +19,7 @@ namespace DropoutCoder.PolylineAlgorithm { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class ExceptionMessageResource { @@ -79,11 +79,11 @@ internal static string ArgumentCannotBeNullOrEmpty { } /// - /// Looks up a localized string similar to Latitude: {0}, Longitude: {1}) is invalid. Latitude must be in range between - 90 and +90. Longitude must be in range between -180 and +180.. + /// Looks up a localized string similar to Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.. /// - internal static string ArgumentExceptionCoordinateIsOutOfRangeErrorMessageFormat { + internal static string CoordinateValidationExceptionCoordinateIsOutOfRangeErrorMessageFormat { get { - return ResourceManager.GetString("ArgumentExceptionCoordinateIsOutOfRangeErrorMessageFormat", resourceCulture); + return ResourceManager.GetString("CoordinateValidationExceptionCoordinateIsOutOfRangeErrorMessageFormat", resourceCulture); } } diff --git a/src/ExceptionMessageResource.resx b/src/ExceptionMessageResource.resx index 24b0415f..04001b03 100644 --- a/src/ExceptionMessageResource.resx +++ b/src/ExceptionMessageResource.resx @@ -123,8 +123,8 @@ Argument cannot be null -or- empty char array. - - Latitude: {0}, Longitude: {1}) is invalid. Latitude must be in range between - 90 and +90. Longitude must be in range between -180 and +180. + + Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180. Polyline is malformed. diff --git a/src/PolylineAlgorithm.cs b/src/PolylineAlgorithm.cs index d5afccb8..2bf148d0 100644 --- a/src/PolylineAlgorithm.cs +++ b/src/PolylineAlgorithm.cs @@ -26,10 +26,10 @@ public static class PolylineAlgorithm /// Returns coordinates. /// If polyline argument is null -or- empty char array. /// If polyline representation is not in correct format. - public static IEnumerable<(double Latitude, double Longitude)> Decode(char[] polyline) + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { // Checking null and at least one character - if (polyline == null || !polyline.Any()) + if (polyline == null || polyline.Length == 0) { throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(polyline)); } @@ -54,14 +54,46 @@ public static class PolylineAlgorithm throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } - var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + // Validating decoded coordinate. If not valid exception is thrown if (!CoordinateValidator.IsValid(coordinate)) { throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } yield return coordinate; + + #region Local functions + + bool TryCalculateNext(string polyline, ref int index, ref int value) + { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; + + do + { + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + double GetCoordinate(int value) + { + return Convert.ToDouble(value) / Constants.Precision; + } + + #endregion } } @@ -74,139 +106,78 @@ public static class PolylineAlgorithm /// If one or more coordinate is out of range public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.Any()) + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(coordinates)); } - // Ensuring coordinates are valid, otherwise throws an aggregate exception - EnsureCoordinates(coordinates); + // Validate collection of coordinates + if (!TryValidate(coordinates, out var exceptions)) + { + throw new AggregateException(exceptions); + } // Initializing local variables int previousLatitude = 0; int previousLongitude = 0; - var sb = _pool.Get(); + var sb = new StringBuilder(coordinates.Count() * 5); // Looping over coordinates and building encoded result foreach (var coordinate in coordinates) { - int latitude = GetIntegerRepresentation(coordinate.Latitude); - int longitude = GetIntegerRepresentation(coordinate.Longitude); + int latitude = Round(coordinate.Latitude); + int longitude = Round(coordinate.Longitude); - sb.Append(GetEncodedCharacters(latitude - previousLatitude).ToArray()); - sb.Append(GetEncodedCharacters(longitude - previousLongitude).ToArray()); + sb.Append(GetSequence(latitude - previousLatitude).ToArray()); + sb.Append(GetSequence(longitude - previousLongitude).ToArray()); previousLatitude = latitude; previousLongitude = longitude; } - var result = sb.ToString(); - - _pool.Return(sb); - - return result; - } + return sb.ToString(); - /// - /// Method performs coordinates validation. Throws exception, if invalid coordinate is found - /// - /// Coordinates to validate - /// If one or more coordinate is out of range -or- invalid - private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) - { - // Selecting invalid coordinates - var invalidCoordinates = coordinates - .Where(c => !CoordinateValidator.IsValid(c)); + #region Local functions - // If any invalid coordinates exists throw an aggregate exception with inner argument out of range exception - if (invalidCoordinates.Any()) + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) { - throw new AggregateException( - ExceptionMessageResource.AggregateExceptionCoordinatesAreInvalidErrorMessage, - invalidCoordinates - .Select(c => - new ArgumentOutOfRangeException( - string.Format( - ExceptionMessageResource.ArgumentExceptionCoordinateIsOutOfRangeErrorMessageFormat, - c.Latitude, - c.Longitude - ) - ) - ) - ); - } - } + exceptions = new List(collection.Count()); - /// - /// - /// - /// Rounded integer representation of precise double value - /// Returns value with specific precision. See - private static double GetDoubleRepresentation(int value) - { - return Convert.ToDouble(value) / Constants.Precision; - } - - /// - /// Method converts value to polyline encoded characters - /// - /// Difference between current and previous latitude or longitude value - private static IEnumerable GetEncodedCharacters(int value) - { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; + foreach (var item in collection) + { + if (!CoordinateValidator.IsValid(item)) + { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); + } + } - int rem = shifted; + return !exceptions.GetEnumerator().MoveNext(); + } - while (rem >= Constants.ASCII.Space) + int Round(double value) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; + return (int)Math.Round(value * Constants.Precision); } - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - /// - /// Method - /// - /// Precise double representation - /// - private static int GetIntegerRepresentation(double value) - { - return (int)Math.Round(value * Constants.Precision); - } - - /// - /// Tries to calculate next integer representation of encoded polyline part - /// - /// The - /// The - /// The - /// The - private static bool TryCalculateNext(char[] polyline, ref int index, ref int value) - { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; + IEnumerable GetSequence(int value) + { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; + int rem = shifted; - do - { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + while (rem >= Constants.ASCII.Space) + { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; + rem >>= Constants.ShiftLength; + } - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + yield return (char)(rem + Constants.ASCII.QuestionMark); + } - return true; + #endregion } } } diff --git a/src/Validation/CoordinateValidationException.cs b/src/Validation/CoordinateValidationException.cs new file mode 100644 index 00000000..fe385b57 --- /dev/null +++ b/src/Validation/CoordinateValidationException.cs @@ -0,0 +1,27 @@ +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace DropoutCoder.PolylineAlgorithm.Validation +{ + using System; + + /// + /// The exception that is thrown when one of the coordinates is not valid. + /// + public class CoordinateValidationException : Exception + { + /// + /// Initializes a new instance of the class with an error message and invalid coordinate values. + /// + /// The latitude value of invalid coodinate + /// The longitude value of invalid coodinate + public CoordinateValidationException(double latitude, double longitude) + : base(string.Format(ExceptionMessageResource.CoordinateValidationExceptionCoordinateIsOutOfRangeErrorMessageFormat, latitude, longitude)) { } + + public double Latitude { get; } + + public double Longitude { get; } + } +} \ No newline at end of file From 7e1a16166db2a189a8e9dc8641ae9849bc6ced27 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 10 Jan 2024 11:21:37 +0100 Subject: [PATCH 012/352] fixed tests --- tests/PolylineAlgorithmTest.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/PolylineAlgorithmTest.cs b/tests/PolylineAlgorithmTest.cs index 317a6472..60d6d0fc 100644 --- a/tests/PolylineAlgorithmTest.cs +++ b/tests/PolylineAlgorithmTest.cs @@ -26,7 +26,7 @@ public class PolylineAlgorithmTest public void Decode_EmptyInput_ThrowsException() { // Arrange - var emptyPolylineCharArray = Defaults.Polyline.Empty.ToCharArray(); + var emptyPolylineCharArray = Defaults.Polyline.Empty; // Act void DecodeEmptyPolylineCharArray() @@ -46,7 +46,7 @@ void DecodeEmptyPolylineCharArray() public void Decode_InvalidInput_ThrowsException() { // Arrange - var invalidPolylineCharrArray = Defaults.Polyline.Invalid.ToCharArray(); + var invalidPolylineCharrArray = Defaults.Polyline.Invalid; // Act void DecodeInvalidPolylineCharArray() @@ -66,7 +66,7 @@ void DecodeInvalidPolylineCharArray() public void Decode_NullInput_ThrowsException() { // Arrange - var nullPolylineCharArray = (char[])null; + var nullPolylineCharArray = (string)null; // Act void DecodeNullPolylineCharArray() @@ -86,7 +86,7 @@ void DecodeNullPolylineCharArray() public void Decode_ValidInput_AreEquivalent() { // Arrange - var validPolylineCharArray = Defaults.Polyline.Valid.ToCharArray(); + var validPolylineCharArray = Defaults.Polyline.Valid; // Act var result = PolylineAlgorithm.Decode(validPolylineCharArray); From c68e7dcc4d1562fd05829eb9d477a0dac4f97149 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 20 May 2024 20:01:29 +0200 Subject: [PATCH 013/352] Ignored BenchmarkDotNet.Artifacts/ folder --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3c4efe20..8791fd0c 100644 --- a/.gitignore +++ b/.gitignore @@ -258,4 +258,7 @@ paket-files/ # Python Tools for Visual Studio (PTVS) __pycache__/ -*.pyc \ No newline at end of file +*.pyc + +# BenchmarkDotNet artifacts +BenchmarkDotNet.Artifacts/ \ No newline at end of file From 98799be1363e4f5d837b016fc6d85a13b1dcbea4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 20 May 2024 20:20:10 +0200 Subject: [PATCH 014/352] Updated algorithm implementation performance benchmarks --- .../DecodePerformanceBenchmark.cs | 119 ++++++++++++-- .../EncodePerformanceBenchmark.cs | 147 +++++++++++++++++- 2 files changed, 250 insertions(+), 16 deletions(-) diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs index 43289f5d..63614d15 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs @@ -2,38 +2,48 @@ { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; + using DropoutCoder.PolylineAlgorithm.Validation; using System; [MemoryDiagnoser] public class DecodePerformanceBenchmark { private Consumer _consumer = new Consumer(); - public static IEnumerable<(int, char[])> Polylines() + public static IEnumerable<(int, string)> Polylines() { - yield return (1, "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI".ToCharArray()); - yield return (2, "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB".ToCharArray()); - yield return (3, "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH".ToCharArray()); + yield return (1, "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"); + yield return (2, "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"); + yield return (3, "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"); } [Benchmark(Baseline = true)] [ArgumentsSource(nameof(Polylines))] - public void Decode_V1((int, char[]) arg) => V1.Decode(arg.Item2).Consume(_consumer); + public void Decode_V1((int, string) arg) => For.Loop(1001, () => V1.Decode(arg.Item2).Consume(_consumer)); [Benchmark] [ArgumentsSource(nameof(Polylines))] - public void Decode_V1_Parallel((int, char[]) arg) => Parallel.For(0, 100, (i) => V1.Decode(arg.Item2).Consume(_consumer)); + public void Decode_V2((int, string) arg) => For.Loop(1001, () => V2.Decode(arg.Item2).Consume(_consumer)); [Benchmark] [ArgumentsSource(nameof(Polylines))] - public void Decode_V2((int, char[]) arg) => V2.Decode(arg.Item2).Consume(_consumer); + public void Decode_V3((int, string) arg) => For.Loop(1001, () => V3.Decode(arg.Item2).Consume(_consumer)); [Benchmark] [ArgumentsSource(nameof(Polylines))] - public void Decode_V2_Parallel((int, char[]) arg) => Parallel.For(0, 100, (i) => V2.Decode(arg.Item2).Consume(_consumer)); + public void Decode_V1_Parallel((int, string) arg) => Parallel.For(0, 1001, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (i) => V1.Decode(arg.Item2).Consume(_consumer)); + + [Benchmark] + [ArgumentsSource(nameof(Polylines))] + public void Decode_V2_Parallel((int, string) arg) => Parallel.For(0, 1001, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (i) => V2.Decode(arg.Item2).Consume(_consumer)); + + [Benchmark] + [ArgumentsSource(nameof(Polylines))] + public void Decode_V3_Parallel((int, string) arg) => Parallel.For(0, 1001, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (i) => V3.Decode(arg.Item2).Consume(_consumer)); + private class V1 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(char[] polyline) + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { if (polyline is null || polyline.Length == 0) { @@ -71,7 +81,7 @@ private class V1 return result; } - private static bool TryCalculateNext(ref char[] polyline, ref int index, ref int value) + private static bool TryCalculateNext(ref string polyline, ref int index, ref int value) { int chunk; int sum = 0; @@ -118,7 +128,7 @@ public static bool IsValidLongitude(double longitude) private class V2 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(char[] polyline) + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { if (polyline is null || polyline.Length == 0) { @@ -152,7 +162,7 @@ private class V2 } } - private static bool TryCalculateNext(ref char[] polyline, ref int offset, ref int value) + private static bool TryCalculateNext(ref string polyline, ref int offset, ref int value) { int chunk; int sum = 0; @@ -196,5 +206,90 @@ public static bool IsValidLongitude(double longitude) } } } + + private class V3 + { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) + { + // Checking null and at least one character + if (polyline == null || polyline.Length == 0) + { + throw new ArgumentException(String.Empty, nameof(polyline)); + } + + // Initialize local variables + int index = 0; + int latitude = 0; + int longitude = 0; + + // Looping through encoded polyline char array + while (index < polyline.Length) + { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref latitude)) + { + throw new InvalidOperationException(String.Empty); + } + + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref longitude)) + { + throw new InvalidOperationException(String.Empty); + } + + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + + // Validating decoded coordinate. If not valid exception is thrown + if (!CoordinateValidator.IsValid(coordinate)) + { + throw new InvalidOperationException(String.Empty); + } + + yield return coordinate; + + #region Local functions + + bool TryCalculateNext(string polyline, ref int index, ref int value) + { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; + + do + { + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + double GetCoordinate(int value) + { + return Convert.ToDouble(value) / Constants.Precision; + } + + #endregion + } + } + } + + internal class For + { + public static void Loop(int count, Action action) + { + for (int i = 0; i < count; i++) + { + action.Invoke(); + } + } + } } } diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs index d7a75e02..843b7a4b 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs @@ -2,6 +2,7 @@ { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; + using DropoutCoder.PolylineAlgorithm.Validation; using Microsoft.Extensions.ObjectPool; using System.Collections.Generic; using System.Text; @@ -20,21 +21,29 @@ public class EncodePerformanceBenchmark [Benchmark(Baseline = true)] [ArgumentsSource(nameof(Coordinates))] - public void Encode_V1((int, IEnumerable<(double, double)>) arg) => V1.Encode(arg.Item2).Consume(_consumer); + public void Encode_V1((int, IEnumerable<(double, double)>) arg) => For.Loop(1001, () => V1.Encode(arg.Item2).Consume(_consumer)); [Benchmark] [ArgumentsSource(nameof(Coordinates))] - public void Encode_V1_Parallel((int, IEnumerable<(double, double)>) arg) => Parallel.For(100, 200, (i) => V1.Encode(arg.Item2).Consume(_consumer)); + public void Encode_V2((int, IEnumerable<(double, double)>) arg) => For.Loop(1001, () => V2.Encode(arg.Item2).Consume(_consumer)); + + [Benchmark] + [ArgumentsSource(nameof(Coordinates))] + public void Encode_V3((int, IEnumerable<(double, double)>) arg) => For.Loop(1001, () => V3.Encode(arg.Item2).Consume(_consumer)); [Benchmark] [ArgumentsSource(nameof(Coordinates))] - public void Encode_V2((int, IEnumerable<(double, double)>) arg) => V2.Encode(arg.Item2).Consume(_consumer); + public void Encode_V1_Parallel((int, IEnumerable<(double, double)>) arg) => Parallel.For(0, 1001, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (i) => V1.Encode(arg.Item2).Consume(_consumer)); + [Benchmark] + [ArgumentsSource(nameof(Coordinates))] + public void Encode_V2_Parallel((int, IEnumerable<(double, double)>) arg) => Parallel.For(0, 1001, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (i) => V2.Encode(arg.Item2).Consume(_consumer)); [Benchmark] [ArgumentsSource(nameof(Coordinates))] - public void Encode_V2_Parallel((int, IEnumerable<(double, double)>) arg) => Parallel.For(100, 200, (i) => V2.Encode(arg.Item2).Consume(_consumer)); + public void Encode_V3_Parallel((int, IEnumerable<(double, double)>) arg) => Parallel.For(0, 1001, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (i) => V3.Encode(arg.Item2).Consume(_consumer)); + private class V1 { @@ -218,5 +227,135 @@ public static bool IsValidLongitude(double longitude) } } } + + private class V3 + { + /// + /// Method encodes coordinates to polyline encoded representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null or empty enumerable + /// If one or more coordinate is out of range + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) + { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) + { + throw new ArgumentException(); + } + + // Validate collection of coordinates + if (!TryValidate(coordinates, out var exceptions)) + { + throw new AggregateException(exceptions); + } + + // Initializing local variables + int previousLatitude = 0; + int previousLongitude = 0; + var sb = new StringBuilder(coordinates.Count() * 4); + + // Looping over coordinates and building encoded result + foreach (var coordinate in coordinates) + { + int latitude = Round(coordinate.Latitude); + int longitude = Round(coordinate.Longitude); + + sb.Append(GetSequence(latitude - previousLatitude).ToArray()); + sb.Append(GetSequence(longitude - previousLongitude).ToArray()); + + previousLatitude = latitude; + previousLongitude = longitude; + } + + return sb.ToString(); + + #region Local functions + + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) + { + exceptions = new List(collection.Count()); + + foreach (var item in collection) + { + if (!CoordinateValidator.IsValid(item)) + { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); + } + } + + return !exceptions.GetEnumerator().MoveNext(); + } + + int Round(double value) + { + return (int)Math.Round(value * Constants.Precision); + } + + IEnumerable GetSequence(int value) + { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) + { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + + rem >>= Constants.ShiftLength; + } + + yield return (char)(rem + Constants.ASCII.QuestionMark); + } + + #endregion + } + + public static class CoordinateValidator + { + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValid((double Latitude, double Longitude) coordinate) + { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + /// + /// Performs latitude validation + /// + /// Latitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLatitude(double latitude) + { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + /// + /// Performs longitude validation + /// + /// Longitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLongitude(double longitude) + { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + } + } + + internal class For + { + public static void Loop(int count, Action action) + { + for (int i = 0; i < count; i++) + { + action.Invoke(); + } + } + } } } From 09386c16321f8c226e73fef5177db12ab9c2e74f Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 20 May 2024 21:34:49 +0200 Subject: [PATCH 015/352] Refactored V2 implementation --- .../PolylineEncodingBenchmark.cs | 10 +- .../DecodePerformanceBenchmark.cs | 35 +++- .../EncodePerformanceBenchmark.cs | 11 +- .../ServiceCollectionExtensions.cs | 21 +- .../DefaultPolylineEncoding.cs} | 131 ++++++------- .../IPolylineEncoding`1.cs} | 0 .../Encoding/PolylineEncoding`1.cs} | 2 +- .../Internal/CoordinateValidator.cs | 1 - .../PolylineAlgorithm.cs | 176 ++++++++++++++++- src/Encoding/PolylineEncoding.cs | 34 ---- src/PolylineAlgorithm.cs | 183 ------------------ .../CoordinateValidationException.cs | 27 --- src/Validation/CoordinateValidator.cs | 43 ---- .../ServiceCollectionExtensionsTests.cs | 5 +- 14 files changed, 312 insertions(+), 367 deletions(-) rename src/DropoutCoder.PolylineAlgorithm/{PolylineEncoder.cs => Encoding/DefaultPolylineEncoding.cs} (53%) rename src/DropoutCoder.PolylineAlgorithm/{IPolylineEncoder.cs => Encoding/IPolylineEncoding`1.cs} (100%) rename src/{Encoding/PolylineEncodingBase.cs => DropoutCoder.PolylineAlgorithm/Encoding/PolylineEncoding`1.cs} (97%) delete mode 100644 src/Encoding/PolylineEncoding.cs delete mode 100644 src/PolylineAlgorithm.cs delete mode 100644 src/Validation/CoordinateValidationException.cs delete mode 100644 src/Validation/CoordinateValidator.cs diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs index 7d7c6d7c..81d94ee0 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs @@ -7,7 +7,7 @@ namespace DropoutCoder.PolylineAlgorithm.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; - using DropoutCoder.PolylineAlgorithm; + using DropoutCoder.PolylineAlgorithm.Encoding; [MemoryDiagnoser] [MarkdownExporter] @@ -20,16 +20,16 @@ public class PolylineEncodingBenchmark public IEnumerable<(double, double)> Coordinates; - internal PolylineEncoder Encoder { get; private set; } + internal DefaultPolylineEncoding Encoder { get; private set; } - public char[] Polyline; + public string Polyline; [GlobalSetup] public void Setup() { - Encoder = new PolylineEncoder(); + Encoder = new DefaultPolylineEncoding(); Coordinates = new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }; - Polyline = "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB".ToCharArray(); + Polyline = "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; } [Benchmark] diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs index 63614d15..19bdc516 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs @@ -2,8 +2,8 @@ { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; - using DropoutCoder.PolylineAlgorithm.Validation; using System; + using System.Runtime.CompilerServices; [MemoryDiagnoser] public class DecodePerformanceBenchmark @@ -279,6 +279,39 @@ double GetCoordinate(int value) #endregion } } + + /// + /// Performs coordinate validation + /// + internal static class CoordinateValidator + { + #region Methods + + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValid((double Latitude, double Longitude) coordinate) + { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValidLatitude(double latitude) + { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValidLongitude(double longitude) + { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + + #endregion + } } internal class For diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs index 843b7a4b..2c681321 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs @@ -2,7 +2,6 @@ { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; - using DropoutCoder.PolylineAlgorithm.Validation; using Microsoft.Extensions.ObjectPool; using System.Collections.Generic; using System.Text; @@ -345,6 +344,16 @@ public static bool IsValidLongitude(double longitude) return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } } + + public class CoordinateValidationException : Exception + { + public CoordinateValidationException(double latitude, double longitude) + : base(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { } + + public double Latitude { get; } + + public double Longitude { get; } + } } internal class For diff --git a/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs b/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs index 388cb02f..da5419dd 100644 --- a/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs @@ -5,14 +5,33 @@ namespace DropoutCoder.PolylineAlgorithm.DependencyInjection { + using DropoutCoder.PolylineAlgorithm.Encoding; using Microsoft.Extensions.DependencyInjection; public static class ServiceCollectionExtensions { + /// + /// Registers singleton instance of to dependency container. + /// + /// Instance of + /// nstance of public static IServiceCollection AddPolylineEncoder(this IServiceCollection services) { return services - .AddSingleton(); + .AddSingleton(); + } + + /// + /// Registers singleton instance of to dependency container. + /// + /// Instance of + /// nstance of + public static IServiceCollection AddPolylineEncoder(this IServiceCollection services) + where TService : class + where TImplementation : class, TService + { + return services + .AddSingleton(); } } } diff --git a/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs b/src/DropoutCoder.PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs similarity index 53% rename from src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs rename to src/DropoutCoder.PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs index f288bb7a..8d35ee97 100644 --- a/src/DropoutCoder.PolylineAlgorithm/PolylineEncoder.cs +++ b/src/DropoutCoder.PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs @@ -3,26 +3,27 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm +using DropoutCoder.PolylineAlgorithm.Internal; + +namespace DropoutCoder.PolylineAlgorithm.Encoding { - using DropoutCoder.PolylineAlgorithm.Internal; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; - public sealed class PolylineEncoder : IPolylineEncoder + public sealed class DefaultPolylineEncoding : IPolylineEncoding<(double Latitude, double Longitude)> { private readonly CoordinateValidator _validator = new CoordinateValidator(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public IEnumerable<(double Latitude, double Longitude)> Decode(char[] polyline) + public IEnumerable<(double Latitude, double Longitude)> Decode(string source) { // Checking null and at least one character - if (polyline == null || polyline.Length == 0) + if (source == null || source.Length == 0) { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(polyline)); + throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(source)); } // Initialize local variables @@ -31,16 +32,16 @@ public sealed class PolylineEncoder : IPolylineEncoder int longitude = 0; // Looping through encoded polyline char array - while (index < polyline.Length) + while (index < source.Length) { // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref latitude)) + if (!TryCalculateNext(ref source, ref index, ref latitude)) { throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref longitude)) + if (!TryCalculateNext(ref source, ref index, ref longitude)) { throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } @@ -54,37 +55,6 @@ public sealed class PolylineEncoder : IPolylineEncoder } yield return coordinate; - - #region Local functions - - bool TryCalculateNext(char[] polyline, ref int index, ref int value) - { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; - - do - { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - double GetCoordinate(int value) - { - return Convert.ToDouble(value) / Constants.Precision; - } - - #endregion } } @@ -121,48 +91,75 @@ public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinate } return sb.ToString(); + } - #region Local functions + #region Private methods - bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) + bool TryCalculateNext(ref string polyline, ref int index, ref int value) + { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; + + do { - exceptions = new List(collection.Count()); + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - foreach (var item in collection) - { - if (!_validator.IsValid(item)) - { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } - } + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; - return !exceptions.GetEnumerator().MoveNext(); - } + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - int Round(double value) + return true; + } + + double GetCoordinate(int value) + { + return Convert.ToDouble(value) / Constants.Precision; + } + + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) + { + exceptions = new List(collection.Count()); + + foreach (var item in collection) { - return (int)Math.Round(value * Constants.Precision); + if (!_validator.IsValid(item)) + { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); + } } - IEnumerable GetSequence(int value) - { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; + return !exceptions.GetEnumerator().MoveNext(); + } - int rem = shifted; + int Round(double value) + { + return (int)Math.Round(value * Constants.Precision); + } - while (rem >= Constants.ASCII.Space) - { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + IEnumerable GetSequence(int value) + { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; - rem >>= Constants.ShiftLength; - } + int rem = shifted; + + while (rem >= Constants.ASCII.Space) + { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - yield return (char)(rem + Constants.ASCII.QuestionMark); + rem >>= Constants.ShiftLength; } - #endregion + yield return (char)(rem + Constants.ASCII.QuestionMark); } + + #endregion } } diff --git a/src/DropoutCoder.PolylineAlgorithm/IPolylineEncoder.cs b/src/DropoutCoder.PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs similarity index 100% rename from src/DropoutCoder.PolylineAlgorithm/IPolylineEncoder.cs rename to src/DropoutCoder.PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs diff --git a/src/Encoding/PolylineEncodingBase.cs b/src/DropoutCoder.PolylineAlgorithm/Encoding/PolylineEncoding`1.cs similarity index 97% rename from src/Encoding/PolylineEncodingBase.cs rename to src/DropoutCoder.PolylineAlgorithm/Encoding/PolylineEncoding`1.cs index e59ef0c2..020277de 100644 --- a/src/Encoding/PolylineEncodingBase.cs +++ b/src/DropoutCoder.PolylineAlgorithm/Encoding/PolylineEncoding`1.cs @@ -13,7 +13,7 @@ namespace DropoutCoder.PolylineAlgorithm.Encoding /// Defines base class for all polyline encodings /// /// - public abstract class PolylineEncodingBase : IPolylineEncoding + public abstract class PolylineEncoding : IPolylineEncoding { /// /// Method performs decode operation and coversion to desired type diff --git a/src/DropoutCoder.PolylineAlgorithm/Internal/CoordinateValidator.cs b/src/DropoutCoder.PolylineAlgorithm/Internal/CoordinateValidator.cs index 6f8824d8..a5ab4f9e 100644 --- a/src/DropoutCoder.PolylineAlgorithm/Internal/CoordinateValidator.cs +++ b/src/DropoutCoder.PolylineAlgorithm/Internal/CoordinateValidator.cs @@ -1,6 +1,5 @@ namespace DropoutCoder.PolylineAlgorithm.Internal { - using System; using System.Runtime.CompilerServices; diff --git a/src/DropoutCoder.PolylineAlgorithm/PolylineAlgorithm.cs b/src/DropoutCoder.PolylineAlgorithm/PolylineAlgorithm.cs index 8b6cffb2..3d2f0248 100644 --- a/src/DropoutCoder.PolylineAlgorithm/PolylineAlgorithm.cs +++ b/src/DropoutCoder.PolylineAlgorithm/PolylineAlgorithm.cs @@ -1,6 +1,180 @@ -namespace DropoutCoder.PolylineAlgorithm +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace DropoutCoder.PolylineAlgorithm { + using DropoutCoder.PolylineAlgorithm.Internal; + using Microsoft.Extensions.ObjectPool; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + + /// + /// Performs polyline algorithm decoding and encoding + /// public static class PolylineAlgorithm { + private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); + private static readonly CoordinateValidator _validator = new CoordinateValidator(); + + /// + /// Method decodes polyline encoded representation to coordinates. + /// + /// Encoded polyline string to decode + /// Returns coordinates. + /// If polyline argument is null -or- empty char array. + /// If polyline representation is not in correct format. + public static IEnumerable<(double Latitude, double Longitude)> Decode(string source) + { + // Checking null and at least one character + if (source == null || source.Length == 0) + { + throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(source)); + } + + // Initialize local variables + int index = 0; + int latitude = 0; + int longitude = 0; + + // Looping through encoded polyline char array + while (index < source.Length) + { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(source, ref index, ref latitude)) + { + throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); + } + + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(source, ref index, ref longitude)) + { + throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); + } + + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + + // Validating decoded coordinate. If not valid exception is thrown + if (!_validator.IsValid(coordinate)) + { + throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); + } + + yield return coordinate; + } + } + + /// + /// Method encodes coordinates to polyline encoded representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null or empty enumerable + /// If one or more coordinate is out of range + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) + { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) + { + throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(coordinates)); + } + + // Validate collection of coordinates + if (!TryValidate(coordinates, out var exceptions)) + { + throw new AggregateException(exceptions); + } + + // Initializing local variables + int previousLatitude = 0; + int previousLongitude = 0; + var sb = _pool.Get(); + + // Looping over coordinates and building encoded result + foreach (var coordinate in coordinates) + { + int latitude = Round(coordinate.Latitude); + int longitude = Round(coordinate.Longitude); + + sb.Append(GetSequence(latitude - previousLatitude).ToArray()); + sb.Append(GetSequence(longitude - previousLongitude).ToArray()); + + previousLatitude = latitude; + previousLongitude = longitude; + } + + return sb.ToString(); + } + + #region Private methods + + static bool TryCalculateNext(string polyline, ref int index, ref int value) + { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; + + do + { + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + static double GetCoordinate(int value) + { + return Convert.ToDouble(value) / Constants.Precision; + } + + static bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) + { + exceptions = new List(collection.Count()); + + foreach (var item in collection) + { + if (!_validator.IsValid(item)) + { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); + } + } + + return !exceptions.GetEnumerator().MoveNext(); + } + + static int Round(double value) + { + return (int)Math.Round(value * Constants.Precision); + } + + static IEnumerable GetSequence(int value) + { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) + { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + + rem >>= Constants.ShiftLength; + } + + yield return (char)(rem + Constants.ASCII.QuestionMark); + } + + #endregion } } diff --git a/src/Encoding/PolylineEncoding.cs b/src/Encoding/PolylineEncoding.cs deleted file mode 100644 index 357c4973..00000000 --- a/src/Encoding/PolylineEncoding.cs +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace DropoutCoder.PolylineAlgorithm.Encoding -{ - /// - /// Defines default polyline encoding with generic - /// - public class PolylineEncoding : PolylineEncodingBase<(double Latitude, double Longitude)> - { - /// - /// Method creates result from passed latitude and longitude arguments - /// - /// Latitude value - /// Longitude value - /// Returns created instance of - protected override (double Latitude, double Longitude) CreateResult(double latitude, double longitude) - { - return (latitude, longitude); - } - - /// - /// Method creates - /// - /// The - /// Returns created coordinate - protected override (double Latitude, double Longitude) GetCoordinate((double Latitude, double Longitude) source) - { - return source; - } - } -} diff --git a/src/PolylineAlgorithm.cs b/src/PolylineAlgorithm.cs deleted file mode 100644 index 2bf148d0..00000000 --- a/src/PolylineAlgorithm.cs +++ /dev/null @@ -1,183 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace DropoutCoder.PolylineAlgorithm -{ - using DropoutCoder.PolylineAlgorithm.Validation; - using Microsoft.Extensions.ObjectPool; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - - /// - /// Performs polyline algorithm decoding and encoding - /// - public static class PolylineAlgorithm - { - private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); - - /// - /// Method decodes polyline encoded representation to coordinates. - /// - /// Encoded polyline char array to decode - /// Returns coordinates. - /// If polyline argument is null -or- empty char array. - /// If polyline representation is not in correct format. - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) - { - // Checking null and at least one character - if (polyline == null || polyline.Length == 0) - { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(polyline)); - } - - // Initialize local variables - int index = 0; - int latitude = 0; - int longitude = 0; - - // Looping through encoded polyline char array - while (index < polyline.Length) - { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref latitude)) - { - throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); - } - - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref longitude)) - { - throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); - } - - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - - // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) - { - throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); - } - - yield return coordinate; - - #region Local functions - - bool TryCalculateNext(string polyline, ref int index, ref int value) - { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; - - do - { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - double GetCoordinate(int value) - { - return Convert.ToDouble(value) / Constants.Precision; - } - - #endregion - } - } - - /// - /// Method encodes coordinates to polyline encoded representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) - { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) - { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(coordinates)); - } - - // Validate collection of coordinates - if (!TryValidate(coordinates, out var exceptions)) - { - throw new AggregateException(exceptions); - } - - // Initializing local variables - int previousLatitude = 0; - int previousLongitude = 0; - var sb = new StringBuilder(coordinates.Count() * 5); - - // Looping over coordinates and building encoded result - foreach (var coordinate in coordinates) - { - int latitude = Round(coordinate.Latitude); - int longitude = Round(coordinate.Longitude); - - sb.Append(GetSequence(latitude - previousLatitude).ToArray()); - sb.Append(GetSequence(longitude - previousLongitude).ToArray()); - - previousLatitude = latitude; - previousLongitude = longitude; - } - - return sb.ToString(); - - #region Local functions - - bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) - { - exceptions = new List(collection.Count()); - - foreach (var item in collection) - { - if (!CoordinateValidator.IsValid(item)) - { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } - } - - return !exceptions.GetEnumerator().MoveNext(); - } - - int Round(double value) - { - return (int)Math.Round(value * Constants.Precision); - } - - IEnumerable GetSequence(int value) - { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) - { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } - - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - #endregion - } - } -} diff --git a/src/Validation/CoordinateValidationException.cs b/src/Validation/CoordinateValidationException.cs deleted file mode 100644 index fe385b57..00000000 --- a/src/Validation/CoordinateValidationException.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace DropoutCoder.PolylineAlgorithm.Validation -{ - using System; - - /// - /// The exception that is thrown when one of the coordinates is not valid. - /// - public class CoordinateValidationException : Exception - { - /// - /// Initializes a new instance of the class with an error message and invalid coordinate values. - /// - /// The latitude value of invalid coodinate - /// The longitude value of invalid coodinate - public CoordinateValidationException(double latitude, double longitude) - : base(string.Format(ExceptionMessageResource.CoordinateValidationExceptionCoordinateIsOutOfRangeErrorMessageFormat, latitude, longitude)) { } - - public double Latitude { get; } - - public double Longitude { get; } - } -} \ No newline at end of file diff --git a/src/Validation/CoordinateValidator.cs b/src/Validation/CoordinateValidator.cs deleted file mode 100644 index 2ae19295..00000000 --- a/src/Validation/CoordinateValidator.cs +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace DropoutCoder.PolylineAlgorithm.Validation -{ - /// - /// Performs coordinate validation - /// - public static class CoordinateValidator - { - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) - { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - /// - /// Performs latitude validation - /// - /// Latitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) - { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - /// - /// Performs longitude validation - /// - /// Longitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) - { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } -} diff --git a/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs b/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs index 941cf008..07f92d8d 100644 --- a/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs +++ b/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs @@ -5,6 +5,7 @@ namespace DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests { + using DropoutCoder.PolylineAlgorithm.Encoding; using Microsoft.Extensions.DependencyInjection; [TestClass] @@ -28,10 +29,10 @@ public void AddDefaultPolylineEncoderTest() // Act var encoder = provider - .GetRequiredService(); + .GetRequiredService(); // Assert - Assert.IsInstanceOfType(encoder); + Assert.IsInstanceOfType(encoder); } } } \ No newline at end of file From 85b68db238ce49f127cfeeaf69b88c8a0f111883 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 11 Dec 2024 16:19:10 +0100 Subject: [PATCH 016/352] renamed project, solution, files, namespaces, etc. --- ...lineAlgorithm.sln => PolylineAlgorithm.sln | 14 +++---- .../PolylineAlgorithm.Benchmarks.csproj} | 2 +- .../PolylineEncodingBenchmark.cs | 4 +- .../Program.cs | 2 +- .../Constants.cs | 2 +- .../DecodePerformanceBenchmark.cs | 2 +- .../EncodePerformanceBenchmark.cs | 2 +- ...lgorithm.Implementation.Benchmarks.csproj} | 0 .../Program.cs | 2 +- docs/api/.manifest | 42 +++++++++---------- ...ec => PolylineAlgorithm.Extensions.nuspec} | 0 ...orithm.nuspec => PolylineAlgorithm.nuspec} | 0 ...ylineAlgorithm.DependencyInjection.csproj} | 2 +- .../ServiceCollectionExtensions.cs | 4 +- .../CoordinateValidationException.cs | 2 +- .../Encoding/DefaultPolylineEncoding.cs | 4 +- .../Encoding/IPolylineEncoding`1.cs | 2 +- .../Encoding/PolylineEncoding`1.cs | 6 +-- .../ExceptionMessageResource.Designer.cs | 4 +- .../ExceptionMessageResource.resx | 0 .../Internal/Constants.cs | 2 +- .../Internal/CoordinateValidator.cs | 2 +- .../PolylineAlgorithm.csproj} | 4 +- .../PolylineEncoder.cs} | 6 +-- tests/Encoding/PolylineEncodingBaseTest.cs | 4 +- tests/Encoding/PolylineEncodingTest.cs | 4 +- .../GlobalUsings.cs | 0 ...lgorithm.DependencyInjection.Tests.csproj} | 2 +- .../ServiceCollectionExtensionsTests.cs | 4 +- .../CoordinateValidatorTest.cs | 4 +- .../Defaults.cs | 2 +- .../GlobalUsings.cs | 0 .../PolylineAlgorithm.Tests.csproj} | 2 +- .../PolylineAlgorithmTest.cs | 33 +++++++-------- .../Properties/AssemblyInfo.cs | 0 tests/Validation/CoordinateValidatorTest.cs | 4 +- 36 files changed, 84 insertions(+), 85 deletions(-) rename DropoutCoder.PolylineAlgorithm.sln => PolylineAlgorithm.sln (70%) rename benchmarks/{DropoutCoder.PolylineAlgorithm.Benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks.csproj => PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj} (76%) rename benchmarks/{DropoutCoder.PolylineAlgorithm.Benchmarks => PolylineAlgorithm.Benchmarks}/PolylineEncodingBenchmark.cs (94%) rename benchmarks/{DropoutCoder.PolylineAlgorithm.Benchmarks => PolylineAlgorithm.Benchmarks}/Program.cs (88%) rename benchmarks/{DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks => PolylineAlgorithm.Implementation.Benchmarks}/Constants.cs (96%) rename benchmarks/{DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks => PolylineAlgorithm.Implementation.Benchmarks}/DecodePerformanceBenchmark.cs (99%) rename benchmarks/{DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks => PolylineAlgorithm.Implementation.Benchmarks}/EncodePerformanceBenchmark.cs (99%) rename benchmarks/{DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks.csproj => PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj} (100%) rename benchmarks/{DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks => PolylineAlgorithm.Implementation.Benchmarks}/Program.cs (87%) rename nuget/{DropoutCoder.PolylineAlgorithm.Extensions.nuspec => PolylineAlgorithm.Extensions.nuspec} (100%) rename nuget/{DropoutCoder.PolylineAlgorithm.nuspec => PolylineAlgorithm.nuspec} (100%) rename src/{DropoutCoder.PolylineAlgorithm.DependencyInjection/DropoutCoder.PolylineAlgorithm.DependencyInjection.csproj => PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj} (76%) rename src/{DropoutCoder.PolylineAlgorithm.DependencyInjection => PolylineAlgorithm.DependencyInjection}/ServiceCollectionExtensions.cs (92%) rename src/{DropoutCoder.PolylineAlgorithm => PolylineAlgorithm}/CoordinateValidationException.cs (90%) rename src/{DropoutCoder.PolylineAlgorithm => PolylineAlgorithm}/Encoding/DefaultPolylineEncoding.cs (98%) rename src/{DropoutCoder.PolylineAlgorithm => PolylineAlgorithm}/Encoding/IPolylineEncoding`1.cs (95%) rename src/{DropoutCoder.PolylineAlgorithm => PolylineAlgorithm}/Encoding/PolylineEncoding`1.cs (93%) rename src/{DropoutCoder.PolylineAlgorithm => PolylineAlgorithm}/ExceptionMessageResource.Designer.cs (95%) rename src/{DropoutCoder.PolylineAlgorithm => PolylineAlgorithm}/ExceptionMessageResource.resx (100%) rename src/{DropoutCoder.PolylineAlgorithm => PolylineAlgorithm}/Internal/Constants.cs (97%) rename src/{DropoutCoder.PolylineAlgorithm => PolylineAlgorithm}/Internal/CoordinateValidator.cs (95%) rename src/{DropoutCoder.PolylineAlgorithm/DropoutCoder.PolylineAlgorithm.csproj => PolylineAlgorithm/PolylineAlgorithm.csproj} (87%) rename src/{DropoutCoder.PolylineAlgorithm/PolylineAlgorithm.cs => PolylineAlgorithm/PolylineEncoder.cs} (98%) rename tests/{DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests => PolylineAlgorithm.DependencyInjection.Tests}/GlobalUsings.cs (100%) rename tests/{DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj => PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj} (82%) rename tests/{DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests => PolylineAlgorithm.DependencyInjection.Tests}/ServiceCollectionExtensionsTests.cs (89%) rename tests/{DropoutCoder.PolylineAlgorithm.Tests => PolylineAlgorithm.Tests}/CoordinateValidatorTest.cs (94%) rename tests/{DropoutCoder.PolylineAlgorithm.Tests => PolylineAlgorithm.Tests}/Defaults.cs (98%) rename tests/{DropoutCoder.PolylineAlgorithm.Tests => PolylineAlgorithm.Tests}/GlobalUsings.cs (100%) rename tests/{DropoutCoder.PolylineAlgorithm.Tests/DropoutCoder.PolylineAlgorithm.Tests.csproj => PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj} (84%) rename tests/{DropoutCoder.PolylineAlgorithm.Tests => PolylineAlgorithm.Tests}/PolylineAlgorithmTest.cs (73%) rename tests/{DropoutCoder.PolylineAlgorithm.Tests => PolylineAlgorithm.Tests}/Properties/AssemblyInfo.cs (100%) diff --git a/DropoutCoder.PolylineAlgorithm.sln b/PolylineAlgorithm.sln similarity index 70% rename from DropoutCoder.PolylineAlgorithm.sln rename to PolylineAlgorithm.sln index 38119837..99bae17f 100644 --- a/DropoutCoder.PolylineAlgorithm.sln +++ b/PolylineAlgorithm.sln @@ -2,7 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.8.34330.188 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm", "src\DropoutCoder.PolylineAlgorithm\DropoutCoder.PolylineAlgorithm.csproj", "{882322A6-E758-4662-8D1C-7C555C8FC3F2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolylineAlgorithm", "src\PolylineAlgorithm\PolylineAlgorithm.csproj", "{882322A6-E758-4662-8D1C-7C555C8FC3F2}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{51C886AF-D610-48A4-9D73-2DEB38742801}" EndProject @@ -10,22 +10,22 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{576FEFFC EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nuget", "nuget", "{7F9807A1-01FF-40C3-9342-3F3F35D632DA}" ProjectSection(SolutionItems) = preProject - nuget\DropoutCoder.PolylineAlgorithm.nuspec = nuget\DropoutCoder.PolylineAlgorithm.nuspec + nuget\PolylineAlgorithm.nuspec = nuget\PolylineAlgorithm.nuspec EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm.Tests", "tests\DropoutCoder.PolylineAlgorithm.Tests\DropoutCoder.PolylineAlgorithm.Tests.csproj", "{30324A08-AA42-425D-87DA-8F9C6AF60454}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolylineAlgorithm.Tests", "tests\PolylineAlgorithm.Tests\PolylineAlgorithm.Tests.csproj", "{30324A08-AA42-425D-87DA-8F9C6AF60454}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{C13E31F9-B8EF-4915-A1C8-BC33F6431EB9}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{33C03F16-4313-4579-87E6-65892AF21D7D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm.Benchmarks", "benchmarks\DropoutCoder.PolylineAlgorithm.Benchmarks\DropoutCoder.PolylineAlgorithm.Benchmarks.csproj", "{9C7CBAD5-415B-4589-86E1-01C849F9C56C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolylineAlgorithm.Benchmarks", "benchmarks\PolylineAlgorithm.Benchmarks\PolylineAlgorithm.Benchmarks.csproj", "{9C7CBAD5-415B-4589-86E1-01C849F9C56C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks", "benchmarks\DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks\DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks.csproj", "{D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolylineAlgorithm.Implementation.Benchmarks", "benchmarks\PolylineAlgorithm.Implementation.Benchmarks\PolylineAlgorithm.Implementation.Benchmarks.csproj", "{D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm.DependencyInjection", "src\DropoutCoder.PolylineAlgorithm.DependencyInjection\DropoutCoder.PolylineAlgorithm.DependencyInjection.csproj", "{0F07B56B-6D9A-4410-BCAB-C6A460C1E44E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolylineAlgorithm.DependencyInjection", "src\PolylineAlgorithm.DependencyInjection\PolylineAlgorithm.DependencyInjection.csproj", "{0F07B56B-6D9A-4410-BCAB-C6A460C1E44E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests", "tests\DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests\DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj", "{9DC1BAD9-60DD-414D-BE88-E181D887A267}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolylineAlgorithm.DependencyInjection.Tests", "tests\PolylineAlgorithm.DependencyInjection.Tests\PolylineAlgorithm.DependencyInjection.Tests.csproj", "{9DC1BAD9-60DD-414D-BE88-E181D887A267}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj similarity index 76% rename from benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks.csproj rename to benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj index 3b478512..d50295e9 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks.csproj +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj @@ -12,7 +12,7 @@ - + diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs similarity index 94% rename from benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs rename to benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs index 81d94ee0..0ad00aeb 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs @@ -3,11 +3,11 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Benchmarks +namespace PolylineAlgorithm.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; - using DropoutCoder.PolylineAlgorithm.Encoding; + using PolylineAlgorithm.Encoding; [MemoryDiagnoser] [MarkdownExporter] diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs similarity index 88% rename from benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/Program.cs rename to benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index 30b8f4a5..a81e519f 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -3,7 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Benchmarks +namespace PolylineAlgorithm.Benchmarks { using BenchmarkDotNet.Running; diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Constants.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs similarity index 96% rename from benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Constants.cs rename to benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs index 9854d042..b2a50ac1 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Constants.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs @@ -3,7 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks +namespace PolylineAlgorithm.Implementation.Benchmarks { /// /// Defines global constant values diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs similarity index 99% rename from benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs rename to benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs index 19bdc516..dab4d450 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs @@ -1,4 +1,4 @@ -namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks +namespace PolylineAlgorithm.Implementation.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs similarity index 99% rename from benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs rename to benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs index 2c681321..cd77b0ad 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs @@ -1,4 +1,4 @@ -namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks +namespace PolylineAlgorithm.Implementation.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj similarity index 100% rename from benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks.csproj rename to benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs similarity index 87% rename from benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Program.cs rename to benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs index de91106e..31ad484f 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs @@ -3,7 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks +namespace PolylineAlgorithm.Implementation.Benchmarks { using BenchmarkDotNet.Running; diff --git a/docs/api/.manifest b/docs/api/.manifest index 794f97a0..bbdf168e 100644 --- a/docs/api/.manifest +++ b/docs/api/.manifest @@ -1,23 +1,23 @@ { - "DropoutCoder.PolylineAlgorithm": "DropoutCoder.PolylineAlgorithm.yml", - "DropoutCoder.PolylineAlgorithm.Encoding": "DropoutCoder.PolylineAlgorithm.Encoding.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.IPolylineEncoding`1": "DropoutCoder.PolylineAlgorithm.Encoding.IPolylineEncoding-1.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.IPolylineEncoding`1.Decode(System.String)": "DropoutCoder.PolylineAlgorithm.Encoding.IPolylineEncoding-1.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.IPolylineEncoding`1.Encode(System.Collections.Generic.IEnumerable{`0})": "DropoutCoder.PolylineAlgorithm.Encoding.IPolylineEncoding-1.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncoding": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncoding.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncoding.CreateResult(System.Double,System.Double)": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncoding.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncoding.GetCoordinate(System.ValueTuple{System.Double,System.Double})": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncoding.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase`1": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase`1.CreateResult(System.Double,System.Double)": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase`1.Decode(System.String)": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase`1.Encode(System.Collections.Generic.IEnumerable{`0})": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", - "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase`1.GetCoordinate(`0)": "DropoutCoder.PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", - "DropoutCoder.PolylineAlgorithm.PolylineAlgorithm": "DropoutCoder.PolylineAlgorithm.PolylineAlgorithm.yml", - "DropoutCoder.PolylineAlgorithm.PolylineAlgorithm.Decode(System.Char[])": "DropoutCoder.PolylineAlgorithm.PolylineAlgorithm.yml", - "DropoutCoder.PolylineAlgorithm.PolylineAlgorithm.Encode(System.Collections.Generic.IEnumerable{System.ValueTuple{System.Double,System.Double}})": "DropoutCoder.PolylineAlgorithm.PolylineAlgorithm.yml", - "DropoutCoder.PolylineAlgorithm.Validation": "DropoutCoder.PolylineAlgorithm.Validation.yml", - "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator": "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator.yml", - "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator.IsValid(System.ValueTuple{System.Double,System.Double})": "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator.yml", - "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator.IsValidLatitude(System.Double)": "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator.yml", - "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator.IsValidLongitude(System.Double)": "DropoutCoder.PolylineAlgorithm.Validation.CoordinateValidator.yml" + "PolylineAlgorithm": "PolylineAlgorithm.yml", + "PolylineAlgorithm.Encoding": "PolylineAlgorithm.Encoding.yml", + "PolylineAlgorithm.Encoding.IPolylineEncoding`1": "PolylineAlgorithm.Encoding.IPolylineEncoding-1.yml", + "PolylineAlgorithm.Encoding.IPolylineEncoding`1.Decode(System.String)": "PolylineAlgorithm.Encoding.IPolylineEncoding-1.yml", + "PolylineAlgorithm.Encoding.IPolylineEncoding`1.Encode(System.Collections.Generic.IEnumerable{`0})": "PolylineAlgorithm.Encoding.IPolylineEncoding-1.yml", + "PolylineAlgorithm.Encoding.PolylineEncoding": "PolylineAlgorithm.Encoding.PolylineEncoding.yml", + "PolylineAlgorithm.Encoding.PolylineEncoding.CreateResult(System.Double,System.Double)": "PolylineAlgorithm.Encoding.PolylineEncoding.yml", + "PolylineAlgorithm.Encoding.PolylineEncoding.GetCoordinate(System.ValueTuple{System.Double,System.Double})": "PolylineAlgorithm.Encoding.PolylineEncoding.yml", + "PolylineAlgorithm.Encoding.PolylineEncodingBase`1": "PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", + "PolylineAlgorithm.Encoding.PolylineEncodingBase`1.CreateResult(System.Double,System.Double)": "PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", + "PolylineAlgorithm.Encoding.PolylineEncodingBase`1.Decode(System.String)": "PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", + "PolylineAlgorithm.Encoding.PolylineEncodingBase`1.Encode(System.Collections.Generic.IEnumerable{`0})": "PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", + "PolylineAlgorithm.Encoding.PolylineEncodingBase`1.GetCoordinate(`0)": "PolylineAlgorithm.Encoding.PolylineEncodingBase-1.yml", + "PolylineAlgorithm.PolylineAlgorithm": "PolylineAlgorithm.PolylineAlgorithm.yml", + "PolylineAlgorithm.PolylineAlgorithm.Decode(System.Char[])": "PolylineAlgorithm.PolylineAlgorithm.yml", + "PolylineAlgorithm.PolylineAlgorithm.Encode(System.Collections.Generic.IEnumerable{System.ValueTuple{System.Double,System.Double}})": "PolylineAlgorithm.PolylineAlgorithm.yml", + "PolylineAlgorithm.Validation": "PolylineAlgorithm.Validation.yml", + "PolylineAlgorithm.Validation.CoordinateValidator": "PolylineAlgorithm.Validation.CoordinateValidator.yml", + "PolylineAlgorithm.Validation.CoordinateValidator.IsValid(System.ValueTuple{System.Double,System.Double})": "PolylineAlgorithm.Validation.CoordinateValidator.yml", + "PolylineAlgorithm.Validation.CoordinateValidator.IsValidLatitude(System.Double)": "PolylineAlgorithm.Validation.CoordinateValidator.yml", + "PolylineAlgorithm.Validation.CoordinateValidator.IsValidLongitude(System.Double)": "PolylineAlgorithm.Validation.CoordinateValidator.yml" } \ No newline at end of file diff --git a/nuget/DropoutCoder.PolylineAlgorithm.Extensions.nuspec b/nuget/PolylineAlgorithm.Extensions.nuspec similarity index 100% rename from nuget/DropoutCoder.PolylineAlgorithm.Extensions.nuspec rename to nuget/PolylineAlgorithm.Extensions.nuspec diff --git a/nuget/DropoutCoder.PolylineAlgorithm.nuspec b/nuget/PolylineAlgorithm.nuspec similarity index 100% rename from nuget/DropoutCoder.PolylineAlgorithm.nuspec rename to nuget/PolylineAlgorithm.nuspec diff --git a/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/DropoutCoder.PolylineAlgorithm.DependencyInjection.csproj b/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj similarity index 76% rename from src/DropoutCoder.PolylineAlgorithm.DependencyInjection/DropoutCoder.PolylineAlgorithm.DependencyInjection.csproj rename to src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj index 87f8a411..0279904e 100644 --- a/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/DropoutCoder.PolylineAlgorithm.DependencyInjection.csproj +++ b/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs b/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs similarity index 92% rename from src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs rename to src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs index da5419dd..4e907a0f 100644 --- a/src/DropoutCoder.PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs @@ -3,10 +3,10 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.DependencyInjection +namespace PolylineAlgorithm.DependencyInjection { - using DropoutCoder.PolylineAlgorithm.Encoding; using Microsoft.Extensions.DependencyInjection; + using PolylineAlgorithm.Encoding; public static class ServiceCollectionExtensions { diff --git a/src/DropoutCoder.PolylineAlgorithm/CoordinateValidationException.cs b/src/PolylineAlgorithm/CoordinateValidationException.cs similarity index 90% rename from src/DropoutCoder.PolylineAlgorithm/CoordinateValidationException.cs rename to src/PolylineAlgorithm/CoordinateValidationException.cs index 19c9d132..742f3799 100644 --- a/src/DropoutCoder.PolylineAlgorithm/CoordinateValidationException.cs +++ b/src/PolylineAlgorithm/CoordinateValidationException.cs @@ -1,4 +1,4 @@ -namespace DropoutCoder.PolylineAlgorithm +namespace PolylineAlgorithm { using System; diff --git a/src/DropoutCoder.PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs b/src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs similarity index 98% rename from src/DropoutCoder.PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs rename to src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs index 8d35ee97..f64bd4a9 100644 --- a/src/DropoutCoder.PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs +++ b/src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs @@ -3,9 +3,9 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -using DropoutCoder.PolylineAlgorithm.Internal; +using PolylineAlgorithm.Internal; -namespace DropoutCoder.PolylineAlgorithm.Encoding +namespace PolylineAlgorithm.Encoding { using System; using System.Collections.Generic; diff --git a/src/DropoutCoder.PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs b/src/PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs similarity index 95% rename from src/DropoutCoder.PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs rename to src/PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs index f03cd15e..1b172934 100644 --- a/src/DropoutCoder.PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs +++ b/src/PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs @@ -3,7 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Encoding +namespace PolylineAlgorithm.Encoding { using System.Collections.Generic; diff --git a/src/DropoutCoder.PolylineAlgorithm/Encoding/PolylineEncoding`1.cs b/src/PolylineAlgorithm/Encoding/PolylineEncoding`1.cs similarity index 93% rename from src/DropoutCoder.PolylineAlgorithm/Encoding/PolylineEncoding`1.cs rename to src/PolylineAlgorithm/Encoding/PolylineEncoding`1.cs index 020277de..57c38264 100644 --- a/src/DropoutCoder.PolylineAlgorithm/Encoding/PolylineEncoding`1.cs +++ b/src/PolylineAlgorithm/Encoding/PolylineEncoding`1.cs @@ -3,7 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Encoding +namespace PolylineAlgorithm.Encoding { using System; using System.Collections.Generic; @@ -27,7 +27,7 @@ public IEnumerable Decode(string polyline) throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(polyline)); } - return PolylineAlgorithm.Decode(polyline) + return PolylineEncoder.Decode(polyline) .Select(c => CreateResult(c.Latitude, c.Longitude)); } @@ -45,7 +45,7 @@ public string Encode(IEnumerable source) var coordinates = source.Select(s => GetCoordinate(s)); - return PolylineAlgorithm.Encode(coordinates); + return PolylineEncoder.Encode(coordinates); } /// diff --git a/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.Designer.cs b/src/PolylineAlgorithm/ExceptionMessageResource.Designer.cs similarity index 95% rename from src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.Designer.cs rename to src/PolylineAlgorithm/ExceptionMessageResource.Designer.cs index 0b13459c..b56ef89d 100644 --- a/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.Designer.cs +++ b/src/PolylineAlgorithm/ExceptionMessageResource.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace DropoutCoder.PolylineAlgorithm { +namespace PolylineAlgorithm { using System; @@ -39,7 +39,7 @@ internal ExceptionMessageResource() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DropoutCoder.PolylineAlgorithm.ExceptionMessageResource", typeof(ExceptionMessageResource).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PolylineAlgorithm.ExceptionMessageResource", typeof(ExceptionMessageResource).Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.resx b/src/PolylineAlgorithm/ExceptionMessageResource.resx similarity index 100% rename from src/DropoutCoder.PolylineAlgorithm/ExceptionMessageResource.resx rename to src/PolylineAlgorithm/ExceptionMessageResource.resx diff --git a/src/DropoutCoder.PolylineAlgorithm/Internal/Constants.cs b/src/PolylineAlgorithm/Internal/Constants.cs similarity index 97% rename from src/DropoutCoder.PolylineAlgorithm/Internal/Constants.cs rename to src/PolylineAlgorithm/Internal/Constants.cs index f6405ab4..8f39fb87 100644 --- a/src/DropoutCoder.PolylineAlgorithm/Internal/Constants.cs +++ b/src/PolylineAlgorithm/Internal/Constants.cs @@ -3,7 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Internal +namespace PolylineAlgorithm.Internal { /// /// Defines global constant values diff --git a/src/DropoutCoder.PolylineAlgorithm/Internal/CoordinateValidator.cs b/src/PolylineAlgorithm/Internal/CoordinateValidator.cs similarity index 95% rename from src/DropoutCoder.PolylineAlgorithm/Internal/CoordinateValidator.cs rename to src/PolylineAlgorithm/Internal/CoordinateValidator.cs index a5ab4f9e..7c90d7cd 100644 --- a/src/DropoutCoder.PolylineAlgorithm/Internal/CoordinateValidator.cs +++ b/src/PolylineAlgorithm/Internal/CoordinateValidator.cs @@ -1,4 +1,4 @@ -namespace DropoutCoder.PolylineAlgorithm.Internal +namespace PolylineAlgorithm.Internal { using System.Runtime.CompilerServices; diff --git a/src/DropoutCoder.PolylineAlgorithm/DropoutCoder.PolylineAlgorithm.csproj b/src/PolylineAlgorithm/PolylineAlgorithm.csproj similarity index 87% rename from src/DropoutCoder.PolylineAlgorithm/DropoutCoder.PolylineAlgorithm.csproj rename to src/PolylineAlgorithm/PolylineAlgorithm.csproj index 129df9d6..3cb49c44 100644 --- a/src/DropoutCoder.PolylineAlgorithm/DropoutCoder.PolylineAlgorithm.csproj +++ b/src/PolylineAlgorithm/PolylineAlgorithm.csproj @@ -5,10 +5,10 @@ - <_Parameter1>DropoutCoder.PolylineAlgorithm.Tests + <_Parameter1>PolylineAlgorithm.Tests - <_Parameter1>DropoutCoder.PolylineAlgorithm.Benchmarks + <_Parameter1>PolylineAlgorithm.Benchmarks diff --git a/src/DropoutCoder.PolylineAlgorithm/PolylineAlgorithm.cs b/src/PolylineAlgorithm/PolylineEncoder.cs similarity index 98% rename from src/DropoutCoder.PolylineAlgorithm/PolylineAlgorithm.cs rename to src/PolylineAlgorithm/PolylineEncoder.cs index 3d2f0248..a2bd8e93 100644 --- a/src/DropoutCoder.PolylineAlgorithm/PolylineAlgorithm.cs +++ b/src/PolylineAlgorithm/PolylineEncoder.cs @@ -3,19 +3,19 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm +namespace PolylineAlgorithm { - using DropoutCoder.PolylineAlgorithm.Internal; using Microsoft.Extensions.ObjectPool; using System; using System.Collections.Generic; using System.Linq; using System.Text; + using PolylineAlgorithm.Internal; /// /// Performs polyline algorithm decoding and encoding /// - public static class PolylineAlgorithm + public static class PolylineEncoder { private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); private static readonly CoordinateValidator _validator = new CoordinateValidator(); diff --git a/tests/Encoding/PolylineEncodingBaseTest.cs b/tests/Encoding/PolylineEncodingBaseTest.cs index fc695653..e202c83e 100644 --- a/tests/Encoding/PolylineEncodingBaseTest.cs +++ b/tests/Encoding/PolylineEncodingBaseTest.cs @@ -3,9 +3,9 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Tests.Encoding +namespace PolylineAlgorithm.Tests.Encoding { - using DropoutCoder.PolylineAlgorithm.Encoding; + using PolylineAlgorithm.Encoding; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; diff --git a/tests/Encoding/PolylineEncodingTest.cs b/tests/Encoding/PolylineEncodingTest.cs index 697eb1a3..ddcf5e00 100644 --- a/tests/Encoding/PolylineEncodingTest.cs +++ b/tests/Encoding/PolylineEncodingTest.cs @@ -3,9 +3,9 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Tests.Encoding +namespace PolylineAlgorithm.Tests.Encoding { - using DropoutCoder.PolylineAlgorithm.Encoding; + using PolylineAlgorithm.Encoding; using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Linq; diff --git a/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs similarity index 100% rename from tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs rename to tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs diff --git a/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj b/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj similarity index 82% rename from tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj rename to tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj index 2168f981..09bd03f9 100644 --- a/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests.csproj +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj @@ -18,7 +18,7 @@ - + diff --git a/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs similarity index 89% rename from tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs rename to tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs index 07f92d8d..9f100178 100644 --- a/tests/DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs @@ -3,10 +3,10 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.DependencyInjection.Tests +namespace PolylineAlgorithm.DependencyInjection.Tests { - using DropoutCoder.PolylineAlgorithm.Encoding; using Microsoft.Extensions.DependencyInjection; + using PolylineAlgorithm.Encoding; [TestClass] public class ServiceCollectionExtensionsTests diff --git a/tests/DropoutCoder.PolylineAlgorithm.Tests/CoordinateValidatorTest.cs b/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs similarity index 94% rename from tests/DropoutCoder.PolylineAlgorithm.Tests/CoordinateValidatorTest.cs rename to tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs index cf977e42..7dd3cba7 100644 --- a/tests/DropoutCoder.PolylineAlgorithm.Tests/CoordinateValidatorTest.cs +++ b/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs @@ -3,9 +3,9 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Tests +namespace PolylineAlgorithm.Tests { - using DropoutCoder.PolylineAlgorithm.Internal; + using PolylineAlgorithm.Internal; /// /// Defines the diff --git a/tests/DropoutCoder.PolylineAlgorithm.Tests/Defaults.cs b/tests/PolylineAlgorithm.Tests/Defaults.cs similarity index 98% rename from tests/DropoutCoder.PolylineAlgorithm.Tests/Defaults.cs rename to tests/PolylineAlgorithm.Tests/Defaults.cs index 26d58866..806f5e26 100644 --- a/tests/DropoutCoder.PolylineAlgorithm.Tests/Defaults.cs +++ b/tests/PolylineAlgorithm.Tests/Defaults.cs @@ -3,7 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Tests +namespace PolylineAlgorithm.Tests { using System; using System.Collections.Generic; diff --git a/tests/DropoutCoder.PolylineAlgorithm.Tests/GlobalUsings.cs b/tests/PolylineAlgorithm.Tests/GlobalUsings.cs similarity index 100% rename from tests/DropoutCoder.PolylineAlgorithm.Tests/GlobalUsings.cs rename to tests/PolylineAlgorithm.Tests/GlobalUsings.cs diff --git a/tests/DropoutCoder.PolylineAlgorithm.Tests/DropoutCoder.PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj similarity index 84% rename from tests/DropoutCoder.PolylineAlgorithm.Tests/DropoutCoder.PolylineAlgorithm.Tests.csproj rename to tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index a64b9d65..74430e39 100644 --- a/tests/DropoutCoder.PolylineAlgorithm.Tests/DropoutCoder.PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -17,7 +17,7 @@ - + \ No newline at end of file diff --git a/tests/DropoutCoder.PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs b/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs similarity index 73% rename from tests/DropoutCoder.PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs rename to tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs index 60d6d0fc..bde0d814 100644 --- a/tests/DropoutCoder.PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs @@ -3,9 +3,8 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Tests +namespace PolylineAlgorithm.Tests { - using DropoutCoder.PolylineAlgorithm; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; @@ -15,11 +14,11 @@ namespace DropoutCoder.PolylineAlgorithm.Tests /// Defines the /// [TestClass] - [TestCategory(nameof(PolylineAlgorithm))] + [TestCategory(nameof(PolylineEncoder))] public class PolylineAlgorithmTest { /// - /// Method is testing method. Empty [] is passed as parameter. + /// Method is testing method. Empty [] is passed as parameter. /// Expected result is . /// [TestMethod] @@ -31,7 +30,7 @@ public void Decode_EmptyInput_ThrowsException() // Act void DecodeEmptyPolylineCharArray() { - PolylineAlgorithm.Decode(emptyPolylineCharArray).ToArray(); + PolylineEncoder.Decode(emptyPolylineCharArray).ToArray(); } // Assert @@ -39,7 +38,7 @@ void DecodeEmptyPolylineCharArray() } /// - /// Method is testing method. [] with invalid coordinates is passed as parameter. + /// Method is testing method. [] with invalid coordinates is passed as parameter. /// Expected result is . /// [TestMethod] @@ -51,7 +50,7 @@ public void Decode_InvalidInput_ThrowsException() // Act void DecodeInvalidPolylineCharArray() { - PolylineAlgorithm.Decode(invalidPolylineCharrArray).ToArray(); + PolylineEncoder.Decode(invalidPolylineCharrArray).ToArray(); } // Assert @@ -59,7 +58,7 @@ void DecodeInvalidPolylineCharArray() } /// - /// Method is testing method. is passed as parameter. + /// Method is testing method. is passed as parameter. /// Expected result is . /// [TestMethod] @@ -71,7 +70,7 @@ public void Decode_NullInput_ThrowsException() // Act void DecodeNullPolylineCharArray() { - PolylineAlgorithm.Decode(nullPolylineCharArray).ToArray(); + PolylineEncoder.Decode(nullPolylineCharArray).ToArray(); } // Assert @@ -79,7 +78,7 @@ void DecodeNullPolylineCharArray() } /// - /// Method is testing method. [] with valid coordinates is passed as parameter. + /// Method is testing method. [] with valid coordinates is passed as parameter. /// Expected result is . /// [TestMethod] @@ -89,14 +88,14 @@ public void Decode_ValidInput_AreEquivalent() var validPolylineCharArray = Defaults.Polyline.Valid; // Act - var result = PolylineAlgorithm.Decode(validPolylineCharArray); + var result = PolylineEncoder.Decode(validPolylineCharArray); // Assert CollectionAssert.AreEquivalent(Defaults.Coordinate.Valid.ToList(), result.ToList()); } /// - /// Method is testing method. Empty is passed as parameter. + /// Method is testing method. Empty is passed as parameter. /// Expected result is . /// [TestMethod] @@ -108,7 +107,7 @@ public void Encode_EmptyInput_ThrowsException() // Act void EncodeEmptyCoordinates() { - PolylineAlgorithm.Encode(emptyCoordinates); + PolylineEncoder.Encode(emptyCoordinates); } // Assert @@ -127,7 +126,7 @@ public void Encode_InvalidInput_ThrowsException() // Act void EncodeInvalidCoordinates() { - PolylineAlgorithm.Encode(invalidCoordinates); + PolylineEncoder.Encode(invalidCoordinates); } // Assert @@ -135,7 +134,7 @@ void EncodeInvalidCoordinates() } /// - /// Method is testing method. is passed as parameter. + /// Method is testing method. is passed as parameter. /// Expected result is . /// [TestMethod] @@ -147,7 +146,7 @@ public void Encode_NullInput_ThrowsException() // Act void EncodeNullCoordinates() { - PolylineAlgorithm.Encode(nullCoordinates); + PolylineEncoder.Encode(nullCoordinates); } // Assert @@ -164,7 +163,7 @@ public void Encode_ValidInput_AreEqual() var validCoordinates = Defaults.Coordinate.Valid; // Act - var result = PolylineAlgorithm.Encode(validCoordinates); + var result = PolylineEncoder.Encode(validCoordinates); // Assert Assert.AreEqual(Defaults.Polyline.Valid, result); diff --git a/tests/DropoutCoder.PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs b/tests/PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs similarity index 100% rename from tests/DropoutCoder.PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs rename to tests/PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Validation/CoordinateValidatorTest.cs b/tests/Validation/CoordinateValidatorTest.cs index d8d0a404..c36946ea 100644 --- a/tests/Validation/CoordinateValidatorTest.cs +++ b/tests/Validation/CoordinateValidatorTest.cs @@ -3,9 +3,9 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Tests.Validation +namespace PolylineAlgorithm.Tests.Validation { - using DropoutCoder.PolylineAlgorithm.Validation; + using PolylineAlgorithm.Validation; using Microsoft.VisualStudio.TestTools.UnitTesting; /// From 3b16bcb21299399ace9332d5a90620091e16311c Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 11 Dec 2024 17:12:16 +0100 Subject: [PATCH 017/352] updated to lang version 13, fixed analyzer issues --- .../PolylineEncodingBenchmark.cs | 8 ++--- .../DecodePerformanceBenchmark.cs | 2 +- .../EncodePerformanceBenchmark.cs | 26 +++++++-------- ...lylineAlgorithm.DependencyInjection.csproj | 30 +++++++++++------ .../Encoding/DefaultPolylineEncoding.cs | 4 +-- .../Internal/CoordinateValidator.cs | 6 ++-- .../PolylineAlgorithm.csproj | 33 ++++++++++++++----- src/PolylineAlgorithm/PolylineEncoder.cs | 4 +-- .../ServiceCollectionExtensionsTests.cs | 9 +---- .../CoordinateValidatorTest.cs | 12 ++----- tests/PolylineAlgorithm.Tests/Defaults.cs | 10 +++--- .../PolylineAlgorithmTest.cs | 4 +-- 12 files changed, 80 insertions(+), 68 deletions(-) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs index 0ad00aeb..578a683d 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs @@ -18,17 +18,17 @@ public class PolylineEncodingBenchmark [Params(1_000, 100_000, 10_000_000, Priority = 2)] public int N; - public IEnumerable<(double, double)> Coordinates; + public required IEnumerable<(double, double)> Coordinates { get; set; } - internal DefaultPolylineEncoding Encoder { get; private set; } + public required DefaultPolylineEncoding Encoder { get; set; } - public string Polyline; + public required string Polyline { get; set; } [GlobalSetup] public void Setup() { Encoder = new DefaultPolylineEncoding(); - Coordinates = new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }; + Coordinates = [(42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620)]; Polyline = "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; } diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs index dab4d450..52f44da6 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs @@ -8,7 +8,7 @@ [MemoryDiagnoser] public class DecodePerformanceBenchmark { - private Consumer _consumer = new Consumer(); + private readonly Consumer _consumer = new(); public static IEnumerable<(int, string)> Polylines() { yield return (1, "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"); diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs index cd77b0ad..71ce6157 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs @@ -9,7 +9,7 @@ [MemoryDiagnoser] public class EncodePerformanceBenchmark { - private Consumer _consumer = new Consumer(); + private readonly Consumer _consumer = new(); public IEnumerable<(int, IEnumerable<(double, double)>)> Coordinates() { @@ -59,10 +59,10 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo int lastLongitude = 0; var sb = new StringBuilder(); - foreach (var coordinate in coordinates) + foreach (var (Latitude, Longitude) in coordinates) { - int latitude = GetIntegerRepresentation(coordinate.Latitude); - int longitude = GetIntegerRepresentation(coordinate.Longitude); + int latitude = GetIntegerRepresentation(Latitude); + int longitude = GetIntegerRepresentation(Longitude); sb.Append(GetEncodedCharacters(latitude - lastLatitude).ToArray()); sb.Append(GetEncodedCharacters(longitude - lastLongitude).ToArray()); @@ -150,10 +150,10 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo var sb = _pool.Get(); - foreach (var coordinate in coordinates) + foreach (var (Latitude, Longitude) in coordinates) { - int latitude = GetIntegerRepresentation(coordinate.Latitude); - int longitude = GetIntegerRepresentation(coordinate.Longitude); + int latitude = GetIntegerRepresentation(Latitude); + int longitude = GetIntegerRepresentation(Longitude); sb.Append(GetEncodedCharacters(latitude - previousLatitude).ToArray()); sb.Append(GetEncodedCharacters(longitude - previousLongitude).ToArray()); @@ -255,10 +255,10 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo var sb = new StringBuilder(coordinates.Count() * 4); // Looping over coordinates and building encoded result - foreach (var coordinate in coordinates) + foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(coordinate.Latitude); - int longitude = Round(coordinate.Longitude); + int latitude = Round(Latitude); + int longitude = Round(Longitude); sb.Append(GetSequence(latitude - previousLatitude).ToArray()); sb.Append(GetSequence(longitude - previousLongitude).ToArray()); @@ -345,11 +345,9 @@ public static bool IsValidLongitude(double longitude) } } - public class CoordinateValidationException : Exception + public class CoordinateValidationException(double latitude, double longitude) + : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { - public CoordinateValidationException(double latitude, double longitude) - : base(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { } - public double Latitude { get; } public double Longitude { get; } diff --git a/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj b/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj index 0279904e..0a37fc1c 100644 --- a/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj +++ b/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj @@ -1,16 +1,26 @@  - - netstandard2.1 - enable - + + netstandard2.1 + 13 + enable + enable + true + - - - + + All + true + true + true + - - - + + + + + + + diff --git a/src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs b/src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs index f64bd4a9..a9eb35a8 100644 --- a/src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs +++ b/src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs @@ -49,7 +49,7 @@ public sealed class DefaultPolylineEncoding : IPolylineEncoding<(double Latitude var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); // Validating decoded coordinate. If not valid exception is thrown - if (!_validator.IsValid(coordinate)) + if (!CoordinateValidator.IsValid(coordinate)) { throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } @@ -128,7 +128,7 @@ bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ou foreach (var item in collection) { - if (!_validator.IsValid(item)) + if (!CoordinateValidator.IsValid(item)) { exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); } diff --git a/src/PolylineAlgorithm/Internal/CoordinateValidator.cs b/src/PolylineAlgorithm/Internal/CoordinateValidator.cs index 7c90d7cd..28bb5fe1 100644 --- a/src/PolylineAlgorithm/Internal/CoordinateValidator.cs +++ b/src/PolylineAlgorithm/Internal/CoordinateValidator.cs @@ -16,19 +16,19 @@ internal class CoordinateValidator /// Coordinate to validate /// Returns validation result. If valid then true, otherwise false. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool IsValid((double Latitude, double Longitude) coordinate) + public static bool IsValid((double Latitude, double Longitude) coordinate) { return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool IsValidLatitude(double latitude) + public static bool IsValidLatitude(double latitude) { return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool IsValidLongitude(double longitude) + public static bool IsValidLongitude(double longitude) { return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } diff --git a/src/PolylineAlgorithm/PolylineAlgorithm.csproj b/src/PolylineAlgorithm/PolylineAlgorithm.csproj index 3cb49c44..504d22fa 100644 --- a/src/PolylineAlgorithm/PolylineAlgorithm.csproj +++ b/src/PolylineAlgorithm/PolylineAlgorithm.csproj @@ -1,19 +1,25 @@  + netstandard2.1 + 13 enable + enable + true + en - - - <_Parameter1>PolylineAlgorithm.Tests - - - <_Parameter1>PolylineAlgorithm.Benchmarks - - + + + All + true + true + true + + + True @@ -21,10 +27,21 @@ ExceptionMessageResource.resx + ResXFileCodeGenerator ExceptionMessageResource.Designer.cs + + + + <_Parameter1>PolylineAlgorithm.Tests + + + <_Parameter1>PolylineAlgorithm.Benchmarks + + + \ No newline at end of file diff --git a/src/PolylineAlgorithm/PolylineEncoder.cs b/src/PolylineAlgorithm/PolylineEncoder.cs index a2bd8e93..50f6cd7a 100644 --- a/src/PolylineAlgorithm/PolylineEncoder.cs +++ b/src/PolylineAlgorithm/PolylineEncoder.cs @@ -58,7 +58,7 @@ public static class PolylineEncoder var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); // Validating decoded coordinate. If not valid exception is thrown - if (!_validator.IsValid(coordinate)) + if (!CoordinateValidator.IsValid(coordinate)) { throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } @@ -143,7 +143,7 @@ static bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collect foreach (var item in collection) { - if (!_validator.IsValid(item)) + if (!CoordinateValidator.IsValid(item)) { exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); } diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs index 9f100178..8c8dcf78 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs @@ -11,14 +11,7 @@ namespace PolylineAlgorithm.DependencyInjection.Tests [TestClass] public class ServiceCollectionExtensionsTests { - internal static IServiceCollection Services { get; private set; } - - [ClassInitialize] - public static void Initialize(TestContext context) - { - Services = new ServiceCollection() - .AddPolylineEncoder(); - } + private static IServiceCollection Services { get; } = new ServiceCollection().AddPolylineEncoder(); [TestMethod] public void AddDefaultPolylineEncoderTest() diff --git a/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs b/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs index 7dd3cba7..7c24f603 100644 --- a/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs +++ b/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs @@ -14,13 +14,7 @@ namespace PolylineAlgorithm.Tests [TestCategory(nameof(CoordinateValidator))] public class CoordinateValidatorTestCoordinate { - internal static CoordinateValidator Validator { get; private set; } - - [ClassInitialize] - public static void Initialize(TestContext context) - { - Validator = new CoordinateValidator(); - } + private static CoordinateValidator Validator { get; } = new CoordinateValidator(); #region Methods @@ -36,7 +30,7 @@ public void IsValid_InvalidInput_IsFalse() foreach (var item in invalidCoordinateCollection) { // Arrange - var result = Validator.IsValid(item); + var result = CoordinateValidator.IsValid(item); // Assert Assert.IsFalse(result); @@ -55,7 +49,7 @@ public void IsValid_ValidInput_IsTrue() foreach (var item in validCoordinateCollection) { // Arrange - var result = Validator.IsValid(item); + var result = CoordinateValidator.IsValid(item); // Assert Assert.IsTrue(result); diff --git a/tests/PolylineAlgorithm.Tests/Defaults.cs b/tests/PolylineAlgorithm.Tests/Defaults.cs index 806f5e26..a1d54f19 100644 --- a/tests/PolylineAlgorithm.Tests/Defaults.cs +++ b/tests/PolylineAlgorithm.Tests/Defaults.cs @@ -22,27 +22,27 @@ public static class Coordinate /// /// Defines empty range of coordinates. Equals to decoded /// - public static readonly IEnumerable<(double Latitude, double Longitude)> Empty = Enumerable.Empty<(double Latitude, double Longitude)>(); + public static readonly IEnumerable<(double Latitude, double Longitude)> Empty = []; /// /// Defines range of invalid coordinates. Equals to decoded /// - public static readonly IEnumerable<(double Latitude, double Longitude)> Invalid = new[] { + public static readonly IEnumerable<(double Latitude, double Longitude)> Invalid = [ (149.47383, 259.06250), (-158.37407, 225.31250), (152.99363, -220.93750), (-144.49024, -274.37500) - }; + ]; /// /// Defines range of valid coordinates. Equals to decoded /// - public static readonly IEnumerable<(double Latitude, double Longitude)> Valid = new[] { + public static readonly IEnumerable<(double Latitude, double Longitude)> Valid = [ (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) - }; + ]; } /// diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs b/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs index bde0d814..90ca0a51 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs @@ -65,7 +65,7 @@ void DecodeInvalidPolylineCharArray() public void Decode_NullInput_ThrowsException() { // Arrange - var nullPolylineCharArray = (string)null; + var nullPolylineCharArray = (string)null!; // Act void DecodeNullPolylineCharArray() @@ -141,7 +141,7 @@ void EncodeInvalidCoordinates() public void Encode_NullInput_ThrowsException() { // Arrange - var nullCoordinates = (IEnumerable<(double, double)>)null; + var nullCoordinates = (IEnumerable<(double, double)>)null!; // Act void EncodeNullCoordinates() From 0f5efe84cad5fac9e792891c6a2f59e716a82e33 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 11 Dec 2024 17:18:59 +0100 Subject: [PATCH 018/352] fixed value for LangVersion --- .../PolylineAlgorithm.DependencyInjection.csproj | 2 +- src/PolylineAlgorithm/PolylineAlgorithm.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj b/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj index 0a37fc1c..4189e5ae 100644 --- a/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj +++ b/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj @@ -2,7 +2,7 @@ netstandard2.1 - 13 + 13.0 enable enable true diff --git a/src/PolylineAlgorithm/PolylineAlgorithm.csproj b/src/PolylineAlgorithm/PolylineAlgorithm.csproj index 504d22fa..06cbd5fe 100644 --- a/src/PolylineAlgorithm/PolylineAlgorithm.csproj +++ b/src/PolylineAlgorithm/PolylineAlgorithm.csproj @@ -2,7 +2,7 @@ netstandard2.1 - 13 + 13.0 enable enable true From 4aca7b51d2fe1f2bc6175c4941c9ea076b60dc76 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 11 Dec 2024 17:23:19 +0100 Subject: [PATCH 019/352] updated LangVersion to 13.0, added additional csproij properties --- .../PolylineAlgorithm.Benchmarks.csproj | 26 +++++++------ ...Algorithm.Implementation.Benchmarks.csproj | 4 +- ...Algorithm.DependencyInjection.Tests.csproj | 38 ++++++++++--------- .../PolylineAlgorithm.Tests.csproj | 8 +++- 4 files changed, 44 insertions(+), 32 deletions(-) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj index d50295e9..7f886722 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj @@ -1,18 +1,20 @@  - - Exe - net8.0 - enable - enable - + + Exe + net8.0 + 13.0 + enable + enable + true + - - - + + + - - - + + + diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj index 03de0360..47834fb9 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj @@ -3,8 +3,10 @@ Exe net8.0 - enable + 13.0 enable + enable + true diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj b/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj index 09bd03f9..310bde91 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj @@ -1,24 +1,28 @@ - - net8.0 - enable - enable + + net8.0 + 13.0 + enable + enable + true + - false - true - + + false + true + - - - - - - - + + + + + + + - - - + + + diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index 74430e39..60555cd3 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -2,9 +2,13 @@ net8.0 - enable + 13.0 enable + enable + true + + false true @@ -17,7 +21,7 @@ - + \ No newline at end of file From ee252571651dedc43f8d9a27d816b442732e7143 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 11 Dec 2024 17:25:51 +0100 Subject: [PATCH 020/352] updated .NET version to 9.0.x --- .github/workflows/dotnet.yml | 2 +- .github/workflows/static.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 0bfc8aa7..235f1efd 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -19,7 +19,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - name: Restore dependencies run: dotnet restore - name: Build diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 1526b959..f7090a3f 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -29,7 +29,7 @@ jobs: - name: Dotnet Setup uses: actions/setup-dotnet@v3 with: - dotnet-version: 8.x + dotnet-version: 9.0.x - run: dotnet tool update -g docfx - run: docfx ./docs/docfx.json From b79f72147c6e875a15ec9311ccede6979ec5dcda Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 11 Dec 2024 18:04:19 +0100 Subject: [PATCH 021/352] updated to .NET 9, nuget packages version are wilcarded for minor version, code styling applied --- .../PolylineAlgorithm.Benchmarks.csproj | 4 +- .../PolylineEncodingBenchmark.cs | 9 +- .../PolylineAlgorithm.Benchmarks/Program.cs | 9 +- .../Constants.cs | 12 +- .../DecodePerformanceBenchmark.cs | 144 ++++++------------ .../EncodePerformanceBenchmark.cs | 144 ++++++------------ ...Algorithm.Implementation.Benchmarks.csproj | 6 +- .../Program.cs | 9 +- ...lylineAlgorithm.DependencyInjection.csproj | 2 +- .../ServiceCollectionExtensions.cs | 12 +- .../CoordinateValidationException.cs | 6 +- .../Encoding/DefaultPolylineEncoding.cs | 63 +++----- .../Encoding/IPolylineEncoding`1.cs | 6 +- .../Encoding/PolylineEncoding`1.cs | 18 +-- src/PolylineAlgorithm/Internal/Constants.cs | 12 +- .../Internal/CoordinateValidator.cs | 15 +- .../PolylineAlgorithm.csproj | 2 +- src/PolylineAlgorithm/PolylineEncoder.cs | 65 +++----- ...Algorithm.DependencyInjection.Tests.csproj | 21 ++- .../ServiceCollectionExtensionsTests.cs | 9 +- .../CoordinateValidatorTest.cs | 18 +-- tests/PolylineAlgorithm.Tests/Defaults.cs | 13 +- tests/PolylineAlgorithm.Tests/GlobalUsings.cs | 2 - .../PolylineAlgorithm.Tests.csproj | 17 ++- .../PolylineAlgorithmTest.cs | 48 ++---- 25 files changed, 237 insertions(+), 429 deletions(-) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj index 7f886722..ce91dbae 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 13.0 enable enable @@ -10,7 +10,7 @@ - + diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs index 578a683d..aca009c0 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs @@ -3,16 +3,14 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Benchmarks -{ +namespace PolylineAlgorithm.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; using PolylineAlgorithm.Encoding; [MemoryDiagnoser] [MarkdownExporter] - public class PolylineEncodingBenchmark - { + public class PolylineEncodingBenchmark { private Consumer _consumer = new Consumer(); [Params(1_000, 100_000, 10_000_000, Priority = 2)] @@ -25,8 +23,7 @@ public class PolylineEncodingBenchmark public required string Polyline { get; set; } [GlobalSetup] - public void Setup() - { + public void Setup() { Encoder = new DefaultPolylineEncoding(); Coordinates = [(42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620)]; Polyline = "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index a81e519f..bf0c4b4e 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -3,14 +3,11 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Benchmarks -{ +namespace PolylineAlgorithm.Benchmarks { using BenchmarkDotNet.Running; - internal class Program - { - static void Main(string[] args) - { + internal class Program { + static void Main(string[] args) { BenchmarkRunner .Run(); } diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs index b2a50ac1..e2ed73ed 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs @@ -3,13 +3,11 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Implementation.Benchmarks -{ +namespace PolylineAlgorithm.Implementation.Benchmarks { /// /// Defines global constant values /// - internal static class Constants - { + internal static class Constants { #region Constants /// @@ -27,8 +25,7 @@ internal static class Constants /// /// Defines ASCII characters constant values /// - internal static class ASCII - { + internal static class ASCII { #region Constants /// @@ -52,8 +49,7 @@ internal static class ASCII /// /// Defines coordinates constant values /// - internal static class Coordinate - { + internal static class Coordinate { #region Constants /// diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs index 52f44da6..739297ef 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs @@ -1,16 +1,13 @@ -namespace PolylineAlgorithm.Implementation.Benchmarks -{ +namespace PolylineAlgorithm.Implementation.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; using System; using System.Runtime.CompilerServices; [MemoryDiagnoser] - public class DecodePerformanceBenchmark - { + public class DecodePerformanceBenchmark { private readonly Consumer _consumer = new(); - public static IEnumerable<(int, string)> Polylines() - { + public static IEnumerable<(int, string)> Polylines() { yield return (1, "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"); yield return (2, "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"); yield return (3, "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"); @@ -41,12 +38,9 @@ public class DecodePerformanceBenchmark public void Decode_V3_Parallel((int, string) arg) => Parallel.For(0, 1001, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (i) => V3.Decode(arg.Item2).Consume(_consumer)); - private class V1 - { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) - { - if (polyline is null || polyline.Length == 0) - { + private class V1 { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + if (polyline is null || polyline.Length == 0) { throw new ArgumentException(nameof(polyline)); } @@ -56,22 +50,18 @@ private class V1 var result = new List<(double Latitude, double Longitude)>(); - while (index < polyline.Length) - { - if (!TryCalculateNext(ref polyline, ref index, ref latitude)) - { + while (index < polyline.Length) { + if (!TryCalculateNext(ref polyline, ref index, ref latitude)) { throw new InvalidOperationException(); } - if (!TryCalculateNext(ref polyline, ref index, ref longitude)) - { + if (!TryCalculateNext(ref polyline, ref index, ref longitude)) { throw new InvalidOperationException(); } var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); - if (!CoordinateValidator.IsValid(coordinate)) - { + if (!CoordinateValidator.IsValid(coordinate)) { throw new InvalidOperationException(); } @@ -81,14 +71,12 @@ private class V1 return result; } - private static bool TryCalculateNext(ref string polyline, ref int index, ref int value) - { + private static bool TryCalculateNext(ref string polyline, ref int index, ref int value) { int chunk; int sum = 0; int shifter = 0; - do - { + do { chunk = polyline[index++] - Constants.ASCII.QuestionMark; sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; shifter += Constants.ShiftLength; @@ -102,36 +90,28 @@ private static bool TryCalculateNext(ref string polyline, ref int index, ref int return true; } - private static double GetDoubleRepresentation(int value) - { + private static double GetDoubleRepresentation(int value) { return Convert.ToDouble(value) / Constants.Precision; } - public static class CoordinateValidator - { - public static bool IsValid((double Latitude, double Longitude) coordinate) - { + public static class CoordinateValidator { + public static bool IsValid((double Latitude, double Longitude) coordinate) { return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); } - public static bool IsValidLatitude(double latitude) - { + public static bool IsValidLatitude(double latitude) { return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; } - public static bool IsValidLongitude(double longitude) - { + public static bool IsValidLongitude(double longitude) { return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } } } - private class V2 - { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) - { - if (polyline is null || polyline.Length == 0) - { + private class V2 { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + if (polyline is null || polyline.Length == 0) { throw new ArgumentException(nameof(polyline)); } @@ -139,22 +119,18 @@ private class V2 int latitude = 0; int longitude = 0; - while (offset < polyline.Length) - { - if (!TryCalculateNext(ref polyline, ref offset, ref latitude)) - { + while (offset < polyline.Length) { + if (!TryCalculateNext(ref polyline, ref offset, ref latitude)) { throw new InvalidOperationException(); } - if (!TryCalculateNext(ref polyline, ref offset, ref longitude)) - { + if (!TryCalculateNext(ref polyline, ref offset, ref longitude)) { throw new InvalidOperationException(); } var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); - if (!CoordinateValidator.IsValid(coordinate)) - { + if (!CoordinateValidator.IsValid(coordinate)) { throw new InvalidOperationException(); } @@ -162,14 +138,12 @@ private class V2 } } - private static bool TryCalculateNext(ref string polyline, ref int offset, ref int value) - { + private static bool TryCalculateNext(ref string polyline, ref int offset, ref int value) { int chunk; int sum = 0; int shifter = 0; - do - { + do { chunk = polyline[offset++] - Constants.ASCII.QuestionMark; sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; shifter += Constants.ShiftLength; @@ -183,37 +157,29 @@ private static bool TryCalculateNext(ref string polyline, ref int offset, ref in return true; } - private static double GetDoubleRepresentation(int value) - { + private static double GetDoubleRepresentation(int value) { return value / Constants.Precision; } - public static class CoordinateValidator - { - public static bool IsValid((double Latitude, double Longitude) coordinate) - { + public static class CoordinateValidator { + public static bool IsValid((double Latitude, double Longitude) coordinate) { return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); } - public static bool IsValidLatitude(double latitude) - { + public static bool IsValidLatitude(double latitude) { return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; } - public static bool IsValidLongitude(double longitude) - { + public static bool IsValidLongitude(double longitude) { return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } } } - private class V3 - { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) - { + private class V3 { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { // Checking null and at least one character - if (polyline == null || polyline.Length == 0) - { + if (polyline == null || polyline.Length == 0) { throw new ArgumentException(String.Empty, nameof(polyline)); } @@ -223,25 +189,21 @@ private class V3 int longitude = 0; // Looping through encoded polyline char array - while (index < polyline.Length) - { + while (index < polyline.Length) { // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref latitude)) - { + if (!TryCalculateNext(polyline, ref index, ref latitude)) { throw new InvalidOperationException(String.Empty); } // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref longitude)) - { + if (!TryCalculateNext(polyline, ref index, ref longitude)) { throw new InvalidOperationException(String.Empty); } var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) - { + if (!CoordinateValidator.IsValid(coordinate)) { throw new InvalidOperationException(String.Empty); } @@ -249,15 +211,13 @@ private class V3 #region Local functions - bool TryCalculateNext(string polyline, ref int index, ref int value) - { + bool TryCalculateNext(string polyline, ref int index, ref int value) { // Local variable initialization int chunk; int sum = 0; int shifter = 0; - do - { + do { chunk = polyline[index++] - Constants.ASCII.QuestionMark; sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; shifter += Constants.ShiftLength; @@ -271,8 +231,7 @@ bool TryCalculateNext(string polyline, ref int index, ref int value) return true; } - double GetCoordinate(int value) - { + double GetCoordinate(int value) { return Convert.ToDouble(value) / Constants.Precision; } @@ -283,8 +242,7 @@ double GetCoordinate(int value) /// /// Performs coordinate validation /// - internal static class CoordinateValidator - { + internal static class CoordinateValidator { #region Methods /// @@ -293,20 +251,17 @@ internal static class CoordinateValidator /// Coordinate to validate /// Returns validation result. If valid then true, otherwise false. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValid((double Latitude, double Longitude) coordinate) - { + public static bool IsValid((double Latitude, double Longitude) coordinate) { return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLatitude(double latitude) - { + public static bool IsValidLatitude(double latitude) { return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLongitude(double longitude) - { + public static bool IsValidLongitude(double longitude) { return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } @@ -314,12 +269,9 @@ public static bool IsValidLongitude(double longitude) } } - internal class For - { - public static void Loop(int count, Action action) - { - for (int i = 0; i < count; i++) - { + internal class For { + public static void Loop(int count, Action action) { + for (int i = 0; i < count; i++) { action.Invoke(); } } diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs index 71ce6157..279e9cc0 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs @@ -1,5 +1,4 @@ -namespace PolylineAlgorithm.Implementation.Benchmarks -{ +namespace PolylineAlgorithm.Implementation.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; using Microsoft.Extensions.ObjectPool; @@ -7,12 +6,10 @@ using System.Text; [MemoryDiagnoser] - public class EncodePerformanceBenchmark - { + public class EncodePerformanceBenchmark { private readonly Consumer _consumer = new(); - public IEnumerable<(int, IEnumerable<(double, double)>)> Coordinates() - { + public IEnumerable<(int, IEnumerable<(double, double)>)> Coordinates() { yield return (1, new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) }); yield return (2, new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }); yield return (3, new[] { (60.81071, -121.40005), (70.05664, -38.43130), (37.52379, -84.83755), (41.85003, 26.25620), (68.04709, 110.63120), (61.48922, 50.16245), (-4.46018, -58.11880), (-32.16061, -3.27505), (-50.89185, -55.30630), (-28.52070, 90.94370), (35.26009, 93.75620), (54.83622, 128.91245), (1.16022, 37.50620), (-44.26398, -131.24380), (-33.34325, 154.22495), (-59.65879, 90.94370), (-62.38215, 0.94370), (72.32117, 40.31870), (64.66910, 2.34995), (-61.04971, -84.83755), (77.10238, -91.86880), (-72.88859, -129.83755), (-69.24987, -24.36880), (77.41254, 119.06870), (-70.69409, 83.91245), (78.85650, 75.47495), (26.83989, 140.16245), (-24.75069, -108.74380), (30.53968, -145.30630), (79.12503, 145.78745), (-34.51006, 133.13120), (-73.29753, -60.93130), (-74.08712, 23.44370), (-76.57404, 100.78745), (-76.57404, 100.78745), (39.72082, 103.59995), (70.99412, 148.59995), (82.27591, 138.75620), (78.29964, -3.27505), (78.29964, -3.27505), (-8.65039, 47.34995) }); @@ -44,12 +41,9 @@ public class EncodePerformanceBenchmark public void Encode_V3_Parallel((int, IEnumerable<(double, double)>) arg) => Parallel.For(0, 1001, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (i) => V3.Encode(arg.Item2).Consume(_consumer)); - private class V1 - { - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) - { - if (coordinates is null || !coordinates.Any()) - { + private class V1 { + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates is null || !coordinates.Any()) { throw new ArgumentException(nameof(coordinates)); } @@ -59,8 +53,7 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo int lastLongitude = 0; var sb = new StringBuilder(); - foreach (var (Latitude, Longitude) in coordinates) - { + foreach (var (Latitude, Longitude) in coordinates) { int latitude = GetIntegerRepresentation(Latitude); int longitude = GetIntegerRepresentation(Longitude); @@ -74,13 +67,11 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo return sb.ToString(); } - private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) - { + private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) { var invalidCoordinates = coordinates .Where(c => !CoordinateValidator.IsValid(c)); - if (invalidCoordinates.Any()) - { + if (invalidCoordinates.Any()) { throw new AggregateException( invalidCoordinates .Select(c => @@ -90,16 +81,14 @@ private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longi } } - private static IEnumerable GetEncodedCharacters(int value) - { + private static IEnumerable GetEncodedCharacters(int value) { int shifted = value << 1; if (value < 0) shifted = ~shifted; int rem = shifted; - while (rem >= Constants.ASCII.Space) - { + while (rem >= Constants.ASCII.Space) { yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); rem >>= Constants.ShiftLength; @@ -108,38 +97,30 @@ private static IEnumerable GetEncodedCharacters(int value) yield return (char)(rem + Constants.ASCII.QuestionMark); } - private static int GetIntegerRepresentation(double value) - { + private static int GetIntegerRepresentation(double value) { return (int)Math.Round(value * Constants.Precision); } - public static class CoordinateValidator - { - public static bool IsValid((double Latitude, double Longitude) coordinate) - { + public static class CoordinateValidator { + public static bool IsValid((double Latitude, double Longitude) coordinate) { return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); } - public static bool IsValidLatitude(double latitude) - { + public static bool IsValidLatitude(double latitude) { return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; } - public static bool IsValidLongitude(double longitude) - { + public static bool IsValidLongitude(double longitude) { return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } } } - private class V2 - { + private class V2 { private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, int.MaxValue); - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) - { - if (coordinates is null || !coordinates.Any()) - { + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates is null || !coordinates.Any()) { throw new ArgumentException(nameof(coordinates)); } @@ -150,8 +131,7 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo var sb = _pool.Get(); - foreach (var (Latitude, Longitude) in coordinates) - { + foreach (var (Latitude, Longitude) in coordinates) { int latitude = GetIntegerRepresentation(Latitude); int longitude = GetIntegerRepresentation(Longitude); @@ -169,13 +149,11 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo return result; } - private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) - { + private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) { var invalidCoordinates = coordinates .Where(c => !CoordinateValidator.IsValid(c)); - if (invalidCoordinates.Any()) - { + if (invalidCoordinates.Any()) { throw new AggregateException( invalidCoordinates .Select(c => @@ -185,16 +163,14 @@ private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longi } } - private static IEnumerable GetEncodedCharacters(int value) - { + private static IEnumerable GetEncodedCharacters(int value) { int shifted = value << 1; if (value < 0) shifted = ~shifted; int rem = shifted; - while (rem >= Constants.ASCII.Space) - { + while (rem >= Constants.ASCII.Space) { yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); rem >>= Constants.ShiftLength; @@ -203,32 +179,26 @@ private static IEnumerable GetEncodedCharacters(int value) yield return (char)(rem + Constants.ASCII.QuestionMark); } - private static int GetIntegerRepresentation(double value) - { + private static int GetIntegerRepresentation(double value) { return (int)Math.Round(value * Constants.Precision); } - public static class CoordinateValidator - { - public static bool IsValid((double Latitude, double Longitude) coordinate) - { + public static class CoordinateValidator { + public static bool IsValid((double Latitude, double Longitude) coordinate) { return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); } - public static bool IsValidLatitude(double latitude) - { + public static bool IsValidLatitude(double latitude) { return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; } - public static bool IsValidLongitude(double longitude) - { + public static bool IsValidLongitude(double longitude) { return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } } } - private class V3 - { + private class V3 { /// /// Method encodes coordinates to polyline encoded representation /// @@ -236,16 +206,13 @@ private class V3 /// Polyline encoded representation /// If coordinates parameter is null or empty enumerable /// If one or more coordinate is out of range - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) - { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) - { + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { throw new ArgumentException(); } // Validate collection of coordinates - if (!TryValidate(coordinates, out var exceptions)) - { + if (!TryValidate(coordinates, out var exceptions)) { throw new AggregateException(exceptions); } @@ -255,8 +222,7 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo var sb = new StringBuilder(coordinates.Count() * 4); // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) - { + foreach (var (Latitude, Longitude) in coordinates) { int latitude = Round(Latitude); int longitude = Round(Longitude); @@ -271,14 +237,11 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo #region Local functions - bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) - { + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) { exceptions = new List(collection.Count()); - foreach (var item in collection) - { - if (!CoordinateValidator.IsValid(item)) - { + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); } } @@ -286,21 +249,18 @@ bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ou return !exceptions.GetEnumerator().MoveNext(); } - int Round(double value) - { + int Round(double value) { return (int)Math.Round(value * Constants.Precision); } - IEnumerable GetSequence(int value) - { + IEnumerable GetSequence(int value) { int shifted = value << 1; if (value < 0) shifted = ~shifted; int rem = shifted; - while (rem >= Constants.ASCII.Space) - { + while (rem >= Constants.ASCII.Space) { yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); rem >>= Constants.ShiftLength; @@ -312,15 +272,13 @@ IEnumerable GetSequence(int value) #endregion } - public static class CoordinateValidator - { + public static class CoordinateValidator { /// /// Performs coordinate validation /// /// Coordinate to validate /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) - { + public static bool IsValid((double Latitude, double Longitude) coordinate) { return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); } @@ -329,8 +287,7 @@ public static bool IsValid((double Latitude, double Longitude) coordinate) /// /// Latitude value to validate /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) - { + public static bool IsValidLatitude(double latitude) { return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; } @@ -339,27 +296,22 @@ public static bool IsValidLatitude(double latitude) /// /// Longitude value to validate /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) - { + public static bool IsValidLongitude(double longitude) { return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } } public class CoordinateValidationException(double latitude, double longitude) - : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) - { + : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { public double Latitude { get; } public double Longitude { get; } } } - internal class For - { - public static void Loop(int count, Action action) - { - for (int i = 0; i < count; i++) - { + internal class For { + public static void Loop(int count, Action action) { + for (int i = 0; i < count; i++) { action.Invoke(); } } diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj index 47834fb9..6d61bb8a 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 13.0 enable enable @@ -10,8 +10,8 @@ - - + + diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs index 31ad484f..6980f744 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs @@ -3,14 +3,11 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Implementation.Benchmarks -{ +namespace PolylineAlgorithm.Implementation.Benchmarks { using BenchmarkDotNet.Running; - internal class Program - { - static void Main(string[] args) - { + internal class Program { + static void Main(string[] args) { BenchmarkRunner .Run(); BenchmarkRunner diff --git a/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj b/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj index 4189e5ae..71ff74b6 100644 --- a/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj +++ b/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs b/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs index 4e907a0f..45e9359d 100644 --- a/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs @@ -3,20 +3,17 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.DependencyInjection -{ +namespace PolylineAlgorithm.DependencyInjection { using Microsoft.Extensions.DependencyInjection; using PolylineAlgorithm.Encoding; - public static class ServiceCollectionExtensions - { + public static class ServiceCollectionExtensions { /// /// Registers singleton instance of to dependency container. /// /// Instance of /// nstance of - public static IServiceCollection AddPolylineEncoder(this IServiceCollection services) - { + public static IServiceCollection AddPolylineEncoder(this IServiceCollection services) { return services .AddSingleton(); } @@ -28,8 +25,7 @@ public static IServiceCollection AddPolylineEncoder(this IServiceCollection serv /// nstance of public static IServiceCollection AddPolylineEncoder(this IServiceCollection services) where TService : class - where TImplementation : class, TService - { + where TImplementation : class, TService { return services .AddSingleton(); } diff --git a/src/PolylineAlgorithm/CoordinateValidationException.cs b/src/PolylineAlgorithm/CoordinateValidationException.cs index 742f3799..34d164d5 100644 --- a/src/PolylineAlgorithm/CoordinateValidationException.cs +++ b/src/PolylineAlgorithm/CoordinateValidationException.cs @@ -1,9 +1,7 @@ -namespace PolylineAlgorithm -{ +namespace PolylineAlgorithm { using System; - public class CoordinateValidationException : Exception - { + public class CoordinateValidationException : Exception { public CoordinateValidationException(double latitude, double longitude) : base(string.Format(ExceptionMessageResource.CoordinateValidationExceptionCoordinateIsOutOfRangeErrorMessageFormat, latitude, longitude)) { } diff --git a/src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs b/src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs index a9eb35a8..867ce823 100644 --- a/src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs +++ b/src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs @@ -5,24 +5,20 @@ using PolylineAlgorithm.Internal; -namespace PolylineAlgorithm.Encoding -{ +namespace PolylineAlgorithm.Encoding { using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; - public sealed class DefaultPolylineEncoding : IPolylineEncoding<(double Latitude, double Longitude)> - { + public sealed class DefaultPolylineEncoding : IPolylineEncoding<(double Latitude, double Longitude)> { private readonly CoordinateValidator _validator = new CoordinateValidator(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public IEnumerable<(double Latitude, double Longitude)> Decode(string source) - { + public IEnumerable<(double Latitude, double Longitude)> Decode(string source) { // Checking null and at least one character - if (source == null || source.Length == 0) - { + if (source == null || source.Length == 0) { throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(source)); } @@ -32,25 +28,21 @@ public sealed class DefaultPolylineEncoding : IPolylineEncoding<(double Latitude int longitude = 0; // Looping through encoded polyline char array - while (index < source.Length) - { + while (index < source.Length) { // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(ref source, ref index, ref latitude)) - { + if (!TryCalculateNext(ref source, ref index, ref latitude)) { throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(ref source, ref index, ref longitude)) - { + if (!TryCalculateNext(ref source, ref index, ref longitude)) { throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) - { + if (!CoordinateValidator.IsValid(coordinate)) { throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } @@ -59,16 +51,13 @@ public sealed class DefaultPolylineEncoding : IPolylineEncoding<(double Latitude } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) - { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) - { + public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(coordinates)); } // Validate collection of coordinates - if (!TryValidate(coordinates, out var exceptions)) - { + if (!TryValidate(coordinates, out var exceptions)) { throw new AggregateException(exceptions); } @@ -78,8 +67,7 @@ public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinate var sb = new StringBuilder(coordinates.Count() * 5); // Looping over coordinates and building encoded result - foreach (var coordinate in coordinates) - { + foreach (var coordinate in coordinates) { int latitude = Round(coordinate.Latitude); int longitude = Round(coordinate.Longitude); @@ -95,15 +83,13 @@ public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinate #region Private methods - bool TryCalculateNext(ref string polyline, ref int index, ref int value) - { + bool TryCalculateNext(ref string polyline, ref int index, ref int value) { // Local variable initialization int chunk; int sum = 0; int shifter = 0; - do - { + do { chunk = polyline[index++] - Constants.ASCII.QuestionMark; sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; shifter += Constants.ShiftLength; @@ -117,19 +103,15 @@ bool TryCalculateNext(ref string polyline, ref int index, ref int value) return true; } - double GetCoordinate(int value) - { + double GetCoordinate(int value) { return Convert.ToDouble(value) / Constants.Precision; } - bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) - { + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) { exceptions = new List(collection.Count()); - foreach (var item in collection) - { - if (!CoordinateValidator.IsValid(item)) - { + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); } } @@ -137,21 +119,18 @@ bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ou return !exceptions.GetEnumerator().MoveNext(); } - int Round(double value) - { + int Round(double value) { return (int)Math.Round(value * Constants.Precision); } - IEnumerable GetSequence(int value) - { + IEnumerable GetSequence(int value) { int shifted = value << 1; if (value < 0) shifted = ~shifted; int rem = shifted; - while (rem >= Constants.ASCII.Space) - { + while (rem >= Constants.ASCII.Space) { yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); rem >>= Constants.ShiftLength; diff --git a/src/PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs b/src/PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs index 1b172934..436b9279 100644 --- a/src/PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs +++ b/src/PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs @@ -3,16 +3,14 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Encoding -{ +namespace PolylineAlgorithm.Encoding { using System.Collections.Generic; /// /// Defines base interface for all polyline encodings /// /// Desired type used to decode to and encode from - public interface IPolylineEncoding - { + public interface IPolylineEncoding { /// /// Method performs decoding from polyline encoded to /// diff --git a/src/PolylineAlgorithm/Encoding/PolylineEncoding`1.cs b/src/PolylineAlgorithm/Encoding/PolylineEncoding`1.cs index 57c38264..60b6f281 100644 --- a/src/PolylineAlgorithm/Encoding/PolylineEncoding`1.cs +++ b/src/PolylineAlgorithm/Encoding/PolylineEncoding`1.cs @@ -3,8 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Encoding -{ +namespace PolylineAlgorithm.Encoding { using System; using System.Collections.Generic; using System.Linq; @@ -13,17 +12,14 @@ namespace PolylineAlgorithm.Encoding /// Defines base class for all polyline encodings /// /// - public abstract class PolylineEncoding : IPolylineEncoding - { + public abstract class PolylineEncoding : IPolylineEncoding { /// /// Method performs decode operation and coversion to desired type /// /// The /// The - public IEnumerable Decode(string polyline) - { - if (string.IsNullOrWhiteSpace(polyline)) - { + public IEnumerable Decode(string polyline) { + if (string.IsNullOrWhiteSpace(polyline)) { throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(polyline)); } @@ -36,10 +32,8 @@ public IEnumerable Decode(string polyline) /// /// The /// The - public string Encode(IEnumerable source) - { - if (source == null || !source.Any()) - { + public string Encode(IEnumerable source) { + if (source == null || !source.Any()) { throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(source)); } diff --git a/src/PolylineAlgorithm/Internal/Constants.cs b/src/PolylineAlgorithm/Internal/Constants.cs index 8f39fb87..84727ea3 100644 --- a/src/PolylineAlgorithm/Internal/Constants.cs +++ b/src/PolylineAlgorithm/Internal/Constants.cs @@ -3,13 +3,11 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Internal -{ +namespace PolylineAlgorithm.Internal { /// /// Defines global constant values /// - internal static class Constants - { + internal static class Constants { /// /// Defines the coordinate precision /// @@ -23,8 +21,7 @@ internal static class Constants /// /// Defines ASCII characters constant values /// - internal static class ASCII - { + internal static class ASCII { /// /// Defines the ASCII Question Mark /// @@ -44,8 +41,7 @@ internal static class ASCII /// /// Defines coordinates constant values /// - internal static class Coordinate - { + internal static class Coordinate { /// /// Defines the maximum value for latitude /// diff --git a/src/PolylineAlgorithm/Internal/CoordinateValidator.cs b/src/PolylineAlgorithm/Internal/CoordinateValidator.cs index 28bb5fe1..6614a464 100644 --- a/src/PolylineAlgorithm/Internal/CoordinateValidator.cs +++ b/src/PolylineAlgorithm/Internal/CoordinateValidator.cs @@ -1,13 +1,11 @@ -namespace PolylineAlgorithm.Internal -{ +namespace PolylineAlgorithm.Internal { using System.Runtime.CompilerServices; /// /// Performs coordinate validation /// - internal class CoordinateValidator - { + internal class CoordinateValidator { #region Methods /// @@ -16,20 +14,17 @@ internal class CoordinateValidator /// Coordinate to validate /// Returns validation result. If valid then true, otherwise false. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValid((double Latitude, double Longitude) coordinate) - { + public static bool IsValid((double Latitude, double Longitude) coordinate) { return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLatitude(double latitude) - { + public static bool IsValidLatitude(double latitude) { return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLongitude(double longitude) - { + public static bool IsValidLongitude(double longitude) { return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } diff --git a/src/PolylineAlgorithm/PolylineAlgorithm.csproj b/src/PolylineAlgorithm/PolylineAlgorithm.csproj index 06cbd5fe..b993823d 100644 --- a/src/PolylineAlgorithm/PolylineAlgorithm.csproj +++ b/src/PolylineAlgorithm/PolylineAlgorithm.csproj @@ -17,7 +17,7 @@ - + diff --git a/src/PolylineAlgorithm/PolylineEncoder.cs b/src/PolylineAlgorithm/PolylineEncoder.cs index 50f6cd7a..89ba9f2a 100644 --- a/src/PolylineAlgorithm/PolylineEncoder.cs +++ b/src/PolylineAlgorithm/PolylineEncoder.cs @@ -3,20 +3,18 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm -{ +namespace PolylineAlgorithm { using Microsoft.Extensions.ObjectPool; + using PolylineAlgorithm.Internal; using System; using System.Collections.Generic; using System.Linq; using System.Text; - using PolylineAlgorithm.Internal; /// /// Performs polyline algorithm decoding and encoding /// - public static class PolylineEncoder - { + public static class PolylineEncoder { private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); private static readonly CoordinateValidator _validator = new CoordinateValidator(); @@ -27,11 +25,9 @@ public static class PolylineEncoder /// Returns coordinates. /// If polyline argument is null -or- empty char array. /// If polyline representation is not in correct format. - public static IEnumerable<(double Latitude, double Longitude)> Decode(string source) - { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string source) { // Checking null and at least one character - if (source == null || source.Length == 0) - { + if (source == null || source.Length == 0) { throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(source)); } @@ -41,25 +37,21 @@ public static class PolylineEncoder int longitude = 0; // Looping through encoded polyline char array - while (index < source.Length) - { + while (index < source.Length) { // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(source, ref index, ref latitude)) - { + if (!TryCalculateNext(source, ref index, ref latitude)) { throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(source, ref index, ref longitude)) - { + if (!TryCalculateNext(source, ref index, ref longitude)) { throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) - { + if (!CoordinateValidator.IsValid(coordinate)) { throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } @@ -74,16 +66,13 @@ public static class PolylineEncoder /// Polyline encoded representation /// If coordinates parameter is null or empty enumerable /// If one or more coordinate is out of range - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) - { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) - { + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(coordinates)); } // Validate collection of coordinates - if (!TryValidate(coordinates, out var exceptions)) - { + if (!TryValidate(coordinates, out var exceptions)) { throw new AggregateException(exceptions); } @@ -93,8 +82,7 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo var sb = _pool.Get(); // Looping over coordinates and building encoded result - foreach (var coordinate in coordinates) - { + foreach (var coordinate in coordinates) { int latitude = Round(coordinate.Latitude); int longitude = Round(coordinate.Longitude); @@ -110,15 +98,13 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo #region Private methods - static bool TryCalculateNext(string polyline, ref int index, ref int value) - { + static bool TryCalculateNext(string polyline, ref int index, ref int value) { // Local variable initialization int chunk; int sum = 0; int shifter = 0; - do - { + do { chunk = polyline[index++] - Constants.ASCII.QuestionMark; sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; shifter += Constants.ShiftLength; @@ -132,19 +118,15 @@ static bool TryCalculateNext(string polyline, ref int index, ref int value) return true; } - static double GetCoordinate(int value) - { + static double GetCoordinate(int value) { return Convert.ToDouble(value) / Constants.Precision; } - static bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) - { + static bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) { exceptions = new List(collection.Count()); - foreach (var item in collection) - { - if (!CoordinateValidator.IsValid(item)) - { + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); } } @@ -152,21 +134,18 @@ static bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collect return !exceptions.GetEnumerator().MoveNext(); } - static int Round(double value) - { + static int Round(double value) { return (int)Math.Round(value * Constants.Precision); } - static IEnumerable GetSequence(int value) - { + static IEnumerable GetSequence(int value) { int shifted = value << 1; if (value < 0) shifted = ~shifted; int rem = shifted; - while (rem >= Constants.ASCII.Space) - { + while (rem >= Constants.ASCII.Space) { yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); rem >>= Constants.ShiftLength; diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj b/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj index 310bde91..e7aa94a3 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj @@ -1,7 +1,7 @@ - + - net8.0 + net9.0 13.0 enable enable @@ -14,11 +14,18 @@ - - - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs index 8c8dcf78..46e10fef 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs @@ -3,19 +3,16 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.DependencyInjection.Tests -{ +namespace PolylineAlgorithm.DependencyInjection.Tests { using Microsoft.Extensions.DependencyInjection; using PolylineAlgorithm.Encoding; [TestClass] - public class ServiceCollectionExtensionsTests - { + public class ServiceCollectionExtensionsTests { private static IServiceCollection Services { get; } = new ServiceCollection().AddPolylineEncoder(); [TestMethod] - public void AddDefaultPolylineEncoderTest() - { + public void AddDefaultPolylineEncoderTest() { // Arrange var provider = Services .BuildServiceProvider(); diff --git a/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs b/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs index 7c24f603..924c277d 100644 --- a/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs +++ b/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs @@ -3,8 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Tests -{ +namespace PolylineAlgorithm.Tests { using PolylineAlgorithm.Internal; /// @@ -12,8 +11,7 @@ namespace PolylineAlgorithm.Tests /// [TestClass] [TestCategory(nameof(CoordinateValidator))] - public class CoordinateValidatorTestCoordinate - { + public class CoordinateValidatorTestCoordinate { private static CoordinateValidator Validator { get; } = new CoordinateValidator(); #region Methods @@ -22,13 +20,11 @@ public class CoordinateValidatorTestCoordinate /// The IsValid_InvalidInput /// [TestMethod] - public void IsValid_InvalidInput_IsFalse() - { + public void IsValid_InvalidInput_IsFalse() { // Act var invalidCoordinateCollection = Defaults.Coordinate.Invalid; - foreach (var item in invalidCoordinateCollection) - { + foreach (var item in invalidCoordinateCollection) { // Arrange var result = CoordinateValidator.IsValid(item); @@ -41,13 +37,11 @@ public void IsValid_InvalidInput_IsFalse() /// The IsValid_ValidInput /// [TestMethod] - public void IsValid_ValidInput_IsTrue() - { + public void IsValid_ValidInput_IsTrue() { // Act var validCoordinateCollection = Defaults.Coordinate.Valid; - foreach (var item in validCoordinateCollection) - { + foreach (var item in validCoordinateCollection) { // Arrange var result = CoordinateValidator.IsValid(item); diff --git a/tests/PolylineAlgorithm.Tests/Defaults.cs b/tests/PolylineAlgorithm.Tests/Defaults.cs index a1d54f19..f7e55538 100644 --- a/tests/PolylineAlgorithm.Tests/Defaults.cs +++ b/tests/PolylineAlgorithm.Tests/Defaults.cs @@ -3,22 +3,18 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Tests -{ +namespace PolylineAlgorithm.Tests { using System; using System.Collections.Generic; - using System.Linq; /// /// Defines default values and objects used for testing purposes /// - public static class Defaults - { + public static class Defaults { /// /// Defines default decoded values and objects udÅ›ed for testing purposes /// - public static class Coordinate - { + public static class Coordinate { /// /// Defines empty range of coordinates. Equals to decoded /// @@ -48,8 +44,7 @@ public static class Coordinate /// /// Defines default encoded values and objects udÅ›ed for testing purposes /// - public static class Polyline - { + public static class Polyline { /// /// Defines empty string of polyline encoded coordinates. Equals to encoded /// diff --git a/tests/PolylineAlgorithm.Tests/GlobalUsings.cs b/tests/PolylineAlgorithm.Tests/GlobalUsings.cs index 2b506c25..14e81db7 100644 --- a/tests/PolylineAlgorithm.Tests/GlobalUsings.cs +++ b/tests/PolylineAlgorithm.Tests/GlobalUsings.cs @@ -5,5 +5,3 @@ global using Microsoft.VisualStudio.TestTools.UnitTesting; global using System; -global using System.Collections.Generic; -global using System.Linq; \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index 60555cd3..3e4935fb 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 13.0 enable enable @@ -14,10 +14,17 @@ - - - - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs b/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs index 90ca0a51..f78254a2 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs @@ -3,8 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Tests -{ +namespace PolylineAlgorithm.Tests { using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; @@ -15,21 +14,18 @@ namespace PolylineAlgorithm.Tests /// [TestClass] [TestCategory(nameof(PolylineEncoder))] - public class PolylineAlgorithmTest - { + public class PolylineAlgorithmTest { /// /// Method is testing method. Empty [] is passed as parameter. /// Expected result is . /// [TestMethod] - public void Decode_EmptyInput_ThrowsException() - { + public void Decode_EmptyInput_ThrowsException() { // Arrange var emptyPolylineCharArray = Defaults.Polyline.Empty; // Act - void DecodeEmptyPolylineCharArray() - { + void DecodeEmptyPolylineCharArray() { PolylineEncoder.Decode(emptyPolylineCharArray).ToArray(); } @@ -42,14 +38,12 @@ void DecodeEmptyPolylineCharArray() /// Expected result is . /// [TestMethod] - public void Decode_InvalidInput_ThrowsException() - { + public void Decode_InvalidInput_ThrowsException() { // Arrange var invalidPolylineCharrArray = Defaults.Polyline.Invalid; // Act - void DecodeInvalidPolylineCharArray() - { + void DecodeInvalidPolylineCharArray() { PolylineEncoder.Decode(invalidPolylineCharrArray).ToArray(); } @@ -62,14 +56,12 @@ void DecodeInvalidPolylineCharArray() /// Expected result is . /// [TestMethod] - public void Decode_NullInput_ThrowsException() - { + public void Decode_NullInput_ThrowsException() { // Arrange var nullPolylineCharArray = (string)null!; // Act - void DecodeNullPolylineCharArray() - { + void DecodeNullPolylineCharArray() { PolylineEncoder.Decode(nullPolylineCharArray).ToArray(); } @@ -82,8 +74,7 @@ void DecodeNullPolylineCharArray() /// Expected result is . /// [TestMethod] - public void Decode_ValidInput_AreEquivalent() - { + public void Decode_ValidInput_AreEquivalent() { // Arrange var validPolylineCharArray = Defaults.Polyline.Valid; @@ -99,14 +90,12 @@ public void Decode_ValidInput_AreEquivalent() /// Expected result is . /// [TestMethod] - public void Encode_EmptyInput_ThrowsException() - { + public void Encode_EmptyInput_ThrowsException() { // Arrange var emptyCoordinates = Defaults.Coordinate.Empty; // Act - void EncodeEmptyCoordinates() - { + void EncodeEmptyCoordinates() { PolylineEncoder.Encode(emptyCoordinates); } @@ -118,14 +107,12 @@ void EncodeEmptyCoordinates() /// The Encode_InvalidInput /// [TestMethod] - public void Encode_InvalidInput_ThrowsException() - { + public void Encode_InvalidInput_ThrowsException() { // Arrange var invalidCoordinates = Defaults.Coordinate.Invalid; // Act - void EncodeInvalidCoordinates() - { + void EncodeInvalidCoordinates() { PolylineEncoder.Encode(invalidCoordinates); } @@ -138,14 +125,12 @@ void EncodeInvalidCoordinates() /// Expected result is . /// [TestMethod] - public void Encode_NullInput_ThrowsException() - { + public void Encode_NullInput_ThrowsException() { // Arrange var nullCoordinates = (IEnumerable<(double, double)>)null!; // Act - void EncodeNullCoordinates() - { + void EncodeNullCoordinates() { PolylineEncoder.Encode(nullCoordinates); } @@ -157,8 +142,7 @@ void EncodeNullCoordinates() /// The Encode_ValidInput /// [TestMethod] - public void Encode_ValidInput_AreEqual() - { + public void Encode_ValidInput_AreEqual() { // Arrange var validCoordinates = Defaults.Coordinate.Valid; From d5e9f463ae2bf5e4a23dab849d6ab026c63a7549 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 11 Dec 2024 18:19:21 +0100 Subject: [PATCH 022/352] added code analysis properties and Ispackagable properties to csproj files --- .../PolylineAlgorithm.Benchmarks.csproj | 11 +++++++++++ ...olylineAlgorithm.Implementation.Benchmarks.csproj | 12 ++++++++++++ .../PolylineAlgorithm.DependencyInjection.csproj | 1 + src/PolylineAlgorithm/PolylineAlgorithm.csproj | 1 + ...olylineAlgorithm.DependencyInjection.Tests.csproj | 7 +++++++ .../PolylineAlgorithm.Tests.csproj | 7 +++++++ 6 files changed, 39 insertions(+) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj index ce91dbae..9ee3c658 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj @@ -9,6 +9,17 @@ true + + false + + + + All + latest + true + true + + diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj index 6d61bb8a..21fedb5b 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj @@ -9,6 +9,18 @@ true + + false + + + + All + latest + true + true + true + + diff --git a/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj b/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj index 71ff74b6..7b94773b 100644 --- a/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj +++ b/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj @@ -10,6 +10,7 @@ All + latest true true true diff --git a/src/PolylineAlgorithm/PolylineAlgorithm.csproj b/src/PolylineAlgorithm/PolylineAlgorithm.csproj index b993823d..1d029f7f 100644 --- a/src/PolylineAlgorithm/PolylineAlgorithm.csproj +++ b/src/PolylineAlgorithm/PolylineAlgorithm.csproj @@ -11,6 +11,7 @@ All + latest true true true diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj b/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj index e7aa94a3..35ab91b3 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj @@ -13,6 +13,13 @@ true + + All + latest + true + true + + diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index 3e4935fb..0fdbdc6b 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -13,6 +13,13 @@ true + + All + latest + true + true + + From 9a0dea6b69ab693bffde77118bc7fe4ef60b5326 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 11 Dec 2024 18:31:22 +0100 Subject: [PATCH 023/352] added AssemblyInfo with [assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] attribute --- .../Properties/AssemblyInfo.cs | 6 ++++++ .../Properties/AssemblyInfo.cs | 15 +++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) create mode 100644 tests/PolylineAlgorithm.DependencyInjection.Tests/Properties/AssemblyInfo.cs diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/Properties/AssemblyInfo.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..e517ce6d --- /dev/null +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs b/tests/PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs index 63a08d67..e517ce6d 100644 --- a/tests/PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs +++ b/tests/PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs @@ -1,11 +1,6 @@ -using System.Reflection; -using System.Runtime.InteropServices; -using Test = Microsoft.VisualStudio.TestTools.UnitTesting; -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// -[assembly: ComVisible(false)] - -[assembly: Guid("30324a08-aa42-425d-87da-8f9c6af60454")] - -[assembly: Test.Parallelize(Scope = Test.ExecutionScope.MethodLevel)] +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] \ No newline at end of file From 7fd66d8286ea7b76634057e1640acc94e56d235e Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 11 Dec 2024 19:06:34 +0100 Subject: [PATCH 024/352] disabled .NET analyzers for test projects --- .../PolylineAlgorithm.DependencyInjection.Tests.csproj | 2 +- tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj b/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj index 35ab91b3..f937732f 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj @@ -17,7 +17,7 @@ All latest true - true + false diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index 0fdbdc6b..ef3223fa 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -17,7 +17,7 @@ All latest true - true + false From 6ba9ba5a41a8d78381320d668748b330af3f58d3 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 11 Dec 2024 19:06:51 +0100 Subject: [PATCH 025/352] added underscores to test method name --- .../ServiceCollectionExtensionsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs index 46e10fef..22024e7c 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs @@ -12,7 +12,7 @@ public class ServiceCollectionExtensionsTests { private static IServiceCollection Services { get; } = new ServiceCollection().AddPolylineEncoder(); [TestMethod] - public void AddDefaultPolylineEncoderTest() { + public void Add_DefaultPolylineEncoder_Test() { // Arrange var provider = Services .BuildServiceProvider(); From 3bceafed8d44fa581bb718bb4653e8841ba94ea2 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 11 Dec 2024 19:07:23 +0100 Subject: [PATCH 026/352] suppressed CA1707:Identifiers should not contain underscores in test projects --- .../GlobalSuppressions.cs | 8 ++++++++ tests/PolylineAlgorithm.Tests/GlobalSuppressions.cs | 8 ++++++++ 2 files changed, 16 insertions(+) create mode 100644 tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalSuppressions.cs create mode 100644 tests/PolylineAlgorithm.Tests/GlobalSuppressions.cs diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalSuppressions.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalSuppressions.cs new file mode 100644 index 00000000..dfd5bb25 --- /dev/null +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Applies only to production code. Test assemblies are not production code.")] diff --git a/tests/PolylineAlgorithm.Tests/GlobalSuppressions.cs b/tests/PolylineAlgorithm.Tests/GlobalSuppressions.cs new file mode 100644 index 00000000..dfd5bb25 --- /dev/null +++ b/tests/PolylineAlgorithm.Tests/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Applies only to production code. Test assemblies are not production code.")] From a463456a2a861979f6002f9e6d466f51e0a85178 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 11 Dec 2024 19:07:50 +0100 Subject: [PATCH 027/352] discarded unused entry method arguments --- benchmarks/PolylineAlgorithm.Benchmarks/Program.cs | 2 +- .../PolylineAlgorithm.Implementation.Benchmarks/Program.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index bf0c4b4e..b7fc86bc 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -7,7 +7,7 @@ namespace PolylineAlgorithm.Benchmarks { using BenchmarkDotNet.Running; internal class Program { - static void Main(string[] args) { + static void Main(string[] _) { BenchmarkRunner .Run(); } diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs index 6980f744..654105a6 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs @@ -7,7 +7,7 @@ namespace PolylineAlgorithm.Implementation.Benchmarks { using BenchmarkDotNet.Running; internal class Program { - static void Main(string[] args) { + static void Main(string[] _) { BenchmarkRunner .Run(); BenchmarkRunner From 362b8369c40302043c0edc8f5a0c196d5314fddb Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 11 Dec 2024 19:22:26 +0100 Subject: [PATCH 028/352] moved using to GlovalUsings.cs --- .../GlobalUsings.cs | 4 +++- .../ServiceCollectionExtensionsTests.cs | 2 -- tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs | 1 - tests/PolylineAlgorithm.Tests/GlobalUsings.cs | 3 +++ tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs | 4 ---- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs index 4d9672a9..0e608465 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs @@ -3,4 +3,6 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -global using Microsoft.VisualStudio.TestTools.UnitTesting; \ No newline at end of file +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.VisualStudio.TestTools.UnitTesting; +global using PolylineAlgorithm.Encoding; \ No newline at end of file diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs index 22024e7c..a029c39f 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs @@ -4,8 +4,6 @@ // namespace PolylineAlgorithm.DependencyInjection.Tests { - using Microsoft.Extensions.DependencyInjection; - using PolylineAlgorithm.Encoding; [TestClass] public class ServiceCollectionExtensionsTests { diff --git a/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs b/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs index 924c277d..430d7155 100644 --- a/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs +++ b/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs @@ -4,7 +4,6 @@ // namespace PolylineAlgorithm.Tests { - using PolylineAlgorithm.Internal; /// /// Defines the diff --git a/tests/PolylineAlgorithm.Tests/GlobalUsings.cs b/tests/PolylineAlgorithm.Tests/GlobalUsings.cs index 14e81db7..597fed58 100644 --- a/tests/PolylineAlgorithm.Tests/GlobalUsings.cs +++ b/tests/PolylineAlgorithm.Tests/GlobalUsings.cs @@ -4,4 +4,7 @@ // global using Microsoft.VisualStudio.TestTools.UnitTesting; +global using PolylineAlgorithm.Internal; global using System; +global using System.Collections.Generic; +global using System.Linq; \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs b/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs index f78254a2..e2bb390f 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs @@ -4,10 +4,6 @@ // namespace PolylineAlgorithm.Tests { - using Microsoft.VisualStudio.TestTools.UnitTesting; - using System; - using System.Collections.Generic; - using System.Linq; /// /// Defines the From 7341c74dd6fece97cb01a289ea1c55ea8d185e11 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Tue, 17 Dec 2024 19:05:40 +0100 Subject: [PATCH 029/352] refactoring --- .editorconfig | 1 + .../PolylineAlgorithm.Benchmarks.csproj | 6 +- .../PolylineDecoderBenchmark.cs | 34 + .../PolylineEncoderBenchmark.cs | 35 + .../PolylineEncodingBenchmark.cs | 42 - .../PolylineAlgorithm.Benchmarks/Program.cs | 2 +- .../DecodePerformanceBenchmark.cs | 280 ------- .../EncodePerformanceBenchmark.cs | 320 -------- ...Algorithm.Implementation.Benchmarks.csproj | 11 +- .../PolylineDecoderBenchmark.cs.cs | 578 +++++++++++++ .../PolylineEncoderBenchmark.cs | 773 ++++++++++++++++++ .../Program.cs | 4 +- ...lylineAlgorithm.DependencyInjection.csproj | 1 + .../ServiceCollectionExtensions.cs | 5 +- .../CoordinateValidationException.cs | 2 +- .../Encoding/DefaultPolylineEncoding.cs | 144 ---- .../Encoding/IPolylineEncoding`1.cs | 28 - .../Encoding/PolylineEncoding`1.cs | 60 -- .../ExceptionMessageResource.Designer.cs | 9 + .../ExceptionMessageResource.resx | 3 + .../Internal/CoordinateValidator.cs | 6 - .../Internal/PolylineDecoder.cs | 72 ++ .../Internal/PolylineEncoder.cs | 95 +++ .../PolylineAlgorithm.csproj | 7 + src/PolylineAlgorithm/PolylineEncoder.cs | 159 ---- .../GlobalUsings.cs | 1 - .../ServiceCollectionExtensionsTests.cs | 22 +- .../PolylineAlgorithmTest.cs | 152 ---- .../PolylineDecoderTest.cs | 69 ++ .../PolylineEncoderTest.cs | 85 ++ 30 files changed, 1787 insertions(+), 1219 deletions(-) create mode 100644 .editorconfig create mode 100644 benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs create mode 100644 benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs delete mode 100644 benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs delete mode 100644 benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs delete mode 100644 benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs create mode 100644 benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs create mode 100644 benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs delete mode 100644 src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs delete mode 100644 src/PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs delete mode 100644 src/PolylineAlgorithm/Encoding/PolylineEncoding`1.cs create mode 100644 src/PolylineAlgorithm/Internal/PolylineDecoder.cs create mode 100644 src/PolylineAlgorithm/Internal/PolylineEncoder.cs delete mode 100644 src/PolylineAlgorithm/PolylineEncoder.cs delete mode 100644 tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs create mode 100644 tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs create mode 100644 tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..f20597a1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1 @@ +file_header_template = //\n// Copyright (c) Petr Šrámek. All rights reserved.\n// Licensed under the MIT License. See LICENSE file in the project root for full license information.\n// \ No newline at end of file diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj index 9ee3c658..6bb7b296 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj @@ -7,6 +7,7 @@ enable enable true + en @@ -14,10 +15,7 @@ - All - latest - true - true + false diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs new file mode 100644 index 00000000..09ddd776 --- /dev/null +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs @@ -0,0 +1,34 @@ +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Benchmarks { + using BenchmarkDotNet.Attributes; + using BenchmarkDotNet.Engines; + using PolylineAlgorithm.Internal; + + [MemoryDiagnoser] + [MarkdownExporter] + public class PolylineDecoderBenchmark { + private Consumer _consumer = new(); + + public PolylineDecoder Decoder { get; set; } + + public static IEnumerable GetPolylines() { + yield return "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; + yield return "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; + yield return "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"; + } + + [GlobalSetup] + public void Setup() { + Decoder = new PolylineDecoder(); + } + + [Benchmark] + [ArgumentsSource(nameof(GetPolylines))] + public IEnumerable<(double, double)> Decode(string polyline) => Decoder + .Decode(polyline); + } +} diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs new file mode 100644 index 00000000..e2d11a93 --- /dev/null +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs @@ -0,0 +1,35 @@ +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Benchmarks { + using BenchmarkDotNet.Attributes; + using BenchmarkDotNet.Engines; + using PolylineAlgorithm.Internal; + + [MemoryDiagnoser] + [MarkdownExporter] + public class PolylineEncoderBenchmark { + private Consumer _consumer = new(); + + public PolylineEncoder Encoder { get; set; } + + public IEnumerable> GetCoordinates() { + yield return new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) }; + yield return new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }; + yield return new[] { (60.81071, -121.40005), (70.05664, -38.43130), (37.52379, -84.83755), (41.85003, 26.25620), (68.04709, 110.63120), (61.48922, 50.16245), (-4.46018, -58.11880), (-32.16061, -3.27505), (-50.89185, -55.30630), (-28.52070, 90.94370), (35.26009, 93.75620), (54.83622, 128.91245), (1.16022, 37.50620), (-44.26398, -131.24380), (-33.34325, 154.22495), (-59.65879, 90.94370), (-62.38215, 0.94370), (72.32117, 40.31870), (64.66910, 2.34995), (-61.04971, -84.83755), (77.10238, -91.86880), (-72.88859, -129.83755), (-69.24987, -24.36880), (77.41254, 119.06870), (-70.69409, 83.91245), (78.85650, 75.47495), (26.83989, 140.16245), (-24.75069, -108.74380), (30.53968, -145.30630), (79.12503, 145.78745), (-34.51006, 133.13120), (-73.29753, -60.93130), (-74.08712, 23.44370), (-76.57404, 100.78745), (-76.57404, 100.78745), (39.72082, 103.59995), (70.99412, 148.59995), (82.27591, 138.75620), (78.29964, -3.27505), (78.29964, -3.27505), (-8.65039, 47.34995) }; + } + + [GlobalSetup] + public void Setup() { + Encoder = new PolylineEncoder(); + } + + [Benchmark] + [ArgumentsSource(nameof(GetCoordinates))] + public void Encode(IEnumerable<(double, double)> coordinates) => Encoder + .Encode(coordinates) + .Consume(_consumer); + } +} diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs deleted file mode 100644 index aca009c0..00000000 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncodingBenchmark.cs +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Benchmarks { - using BenchmarkDotNet.Attributes; - using BenchmarkDotNet.Engines; - using PolylineAlgorithm.Encoding; - - [MemoryDiagnoser] - [MarkdownExporter] - public class PolylineEncodingBenchmark { - private Consumer _consumer = new Consumer(); - - [Params(1_000, 100_000, 10_000_000, Priority = 2)] - public int N; - - public required IEnumerable<(double, double)> Coordinates { get; set; } - - public required DefaultPolylineEncoding Encoder { get; set; } - - public required string Polyline { get; set; } - - [GlobalSetup] - public void Setup() { - Encoder = new DefaultPolylineEncoding(); - Coordinates = [(42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620)]; - Polyline = "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; - } - - [Benchmark] - public void Decode() => Encoder - .Decode(Polyline) - .Consume(_consumer); - - [Benchmark] - public void Encode() => Encoder - .Encode(Coordinates) - .Consume(_consumer); - } -} diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index b7fc86bc..5ce7f56f 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -9,7 +9,7 @@ namespace PolylineAlgorithm.Benchmarks { internal class Program { static void Main(string[] _) { BenchmarkRunner - .Run(); + .Run(); } } } diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs deleted file mode 100644 index 739297ef..00000000 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs +++ /dev/null @@ -1,280 +0,0 @@ -namespace PolylineAlgorithm.Implementation.Benchmarks { - using BenchmarkDotNet.Attributes; - using BenchmarkDotNet.Engines; - using System; - using System.Runtime.CompilerServices; - - [MemoryDiagnoser] - public class DecodePerformanceBenchmark { - private readonly Consumer _consumer = new(); - public static IEnumerable<(int, string)> Polylines() { - yield return (1, "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"); - yield return (2, "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"); - yield return (3, "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"); - } - - [Benchmark(Baseline = true)] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V1((int, string) arg) => For.Loop(1001, () => V1.Decode(arg.Item2).Consume(_consumer)); - - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V2((int, string) arg) => For.Loop(1001, () => V2.Decode(arg.Item2).Consume(_consumer)); - - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V3((int, string) arg) => For.Loop(1001, () => V3.Decode(arg.Item2).Consume(_consumer)); - - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V1_Parallel((int, string) arg) => Parallel.For(0, 1001, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (i) => V1.Decode(arg.Item2).Consume(_consumer)); - - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V2_Parallel((int, string) arg) => Parallel.For(0, 1001, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (i) => V2.Decode(arg.Item2).Consume(_consumer)); - - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V3_Parallel((int, string) arg) => Parallel.For(0, 1001, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (i) => V3.Decode(arg.Item2).Consume(_consumer)); - - - private class V1 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - if (polyline is null || polyline.Length == 0) { - throw new ArgumentException(nameof(polyline)); - } - - int index = 0; - int latitude = 0; - int longitude = 0; - - var result = new List<(double Latitude, double Longitude)>(); - - while (index < polyline.Length) { - if (!TryCalculateNext(ref polyline, ref index, ref latitude)) { - throw new InvalidOperationException(); - } - - if (!TryCalculateNext(ref polyline, ref index, ref longitude)) { - throw new InvalidOperationException(); - } - - var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); - - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(); - } - - result.Add(coordinate); - } - - return result; - } - - private static bool TryCalculateNext(ref string polyline, ref int index, ref int value) { - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - private static double GetDoubleRepresentation(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } - - public static class CoordinateValidator { - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - } - - private class V2 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - if (polyline is null || polyline.Length == 0) { - throw new ArgumentException(nameof(polyline)); - } - - int offset = 0; - int latitude = 0; - int longitude = 0; - - while (offset < polyline.Length) { - if (!TryCalculateNext(ref polyline, ref offset, ref latitude)) { - throw new InvalidOperationException(); - } - - if (!TryCalculateNext(ref polyline, ref offset, ref longitude)) { - throw new InvalidOperationException(); - } - - var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); - - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(); - } - - yield return (latitude, longitude); - } - } - - private static bool TryCalculateNext(ref string polyline, ref int offset, ref int value) { - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline[offset++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && offset < polyline.Length); - - if (offset >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - private static double GetDoubleRepresentation(int value) { - return value / Constants.Precision; - } - - public static class CoordinateValidator { - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - } - - private class V3 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - // Checking null and at least one character - if (polyline == null || polyline.Length == 0) { - throw new ArgumentException(String.Empty, nameof(polyline)); - } - - // Initialize local variables - int index = 0; - int latitude = 0; - int longitude = 0; - - // Looping through encoded polyline char array - while (index < polyline.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref latitude)) { - throw new InvalidOperationException(String.Empty); - } - - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref longitude)) { - throw new InvalidOperationException(String.Empty); - } - - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - - // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(String.Empty); - } - - yield return coordinate; - - #region Local functions - - bool TryCalculateNext(string polyline, ref int index, ref int value) { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - double GetCoordinate(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } - - #endregion - } - } - - /// - /// Performs coordinate validation - /// - internal static class CoordinateValidator { - #region Methods - - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - - #endregion - } - } - - internal class For { - public static void Loop(int count, Action action) { - for (int i = 0; i < count; i++) { - action.Invoke(); - } - } - } - } -} diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs deleted file mode 100644 index 279e9cc0..00000000 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs +++ /dev/null @@ -1,320 +0,0 @@ -namespace PolylineAlgorithm.Implementation.Benchmarks { - using BenchmarkDotNet.Attributes; - using BenchmarkDotNet.Engines; - using Microsoft.Extensions.ObjectPool; - using System.Collections.Generic; - using System.Text; - - [MemoryDiagnoser] - public class EncodePerformanceBenchmark { - private readonly Consumer _consumer = new(); - - public IEnumerable<(int, IEnumerable<(double, double)>)> Coordinates() { - yield return (1, new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) }); - yield return (2, new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }); - yield return (3, new[] { (60.81071, -121.40005), (70.05664, -38.43130), (37.52379, -84.83755), (41.85003, 26.25620), (68.04709, 110.63120), (61.48922, 50.16245), (-4.46018, -58.11880), (-32.16061, -3.27505), (-50.89185, -55.30630), (-28.52070, 90.94370), (35.26009, 93.75620), (54.83622, 128.91245), (1.16022, 37.50620), (-44.26398, -131.24380), (-33.34325, 154.22495), (-59.65879, 90.94370), (-62.38215, 0.94370), (72.32117, 40.31870), (64.66910, 2.34995), (-61.04971, -84.83755), (77.10238, -91.86880), (-72.88859, -129.83755), (-69.24987, -24.36880), (77.41254, 119.06870), (-70.69409, 83.91245), (78.85650, 75.47495), (26.83989, 140.16245), (-24.75069, -108.74380), (30.53968, -145.30630), (79.12503, 145.78745), (-34.51006, 133.13120), (-73.29753, -60.93130), (-74.08712, 23.44370), (-76.57404, 100.78745), (-76.57404, 100.78745), (39.72082, 103.59995), (70.99412, 148.59995), (82.27591, 138.75620), (78.29964, -3.27505), (78.29964, -3.27505), (-8.65039, 47.34995) }); - } - - [Benchmark(Baseline = true)] - [ArgumentsSource(nameof(Coordinates))] - public void Encode_V1((int, IEnumerable<(double, double)>) arg) => For.Loop(1001, () => V1.Encode(arg.Item2).Consume(_consumer)); - - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public void Encode_V2((int, IEnumerable<(double, double)>) arg) => For.Loop(1001, () => V2.Encode(arg.Item2).Consume(_consumer)); - - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public void Encode_V3((int, IEnumerable<(double, double)>) arg) => For.Loop(1001, () => V3.Encode(arg.Item2).Consume(_consumer)); - - - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public void Encode_V1_Parallel((int, IEnumerable<(double, double)>) arg) => Parallel.For(0, 1001, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (i) => V1.Encode(arg.Item2).Consume(_consumer)); - - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public void Encode_V2_Parallel((int, IEnumerable<(double, double)>) arg) => Parallel.For(0, 1001, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (i) => V2.Encode(arg.Item2).Consume(_consumer)); - - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public void Encode_V3_Parallel((int, IEnumerable<(double, double)>) arg) => Parallel.For(0, 1001, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (i) => V3.Encode(arg.Item2).Consume(_consumer)); - - - private class V1 { - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates is null || !coordinates.Any()) { - throw new ArgumentException(nameof(coordinates)); - } - - EnsureCoordinates(coordinates); - - int lastLatitude = 0; - int lastLongitude = 0; - var sb = new StringBuilder(); - - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = GetIntegerRepresentation(Latitude); - int longitude = GetIntegerRepresentation(Longitude); - - sb.Append(GetEncodedCharacters(latitude - lastLatitude).ToArray()); - sb.Append(GetEncodedCharacters(longitude - lastLongitude).ToArray()); - - lastLatitude = latitude; - lastLongitude = longitude; - } - - return sb.ToString(); - } - - private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) { - var invalidCoordinates = coordinates - .Where(c => !CoordinateValidator.IsValid(c)); - - if (invalidCoordinates.Any()) { - throw new AggregateException( - invalidCoordinates - .Select(c => - new ArgumentOutOfRangeException() - ) - ); - } - } - - private static IEnumerable GetEncodedCharacters(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } - - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - private static int GetIntegerRepresentation(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - public static class CoordinateValidator { - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - } - - private class V2 { - private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, int.MaxValue); - - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates is null || !coordinates.Any()) { - throw new ArgumentException(nameof(coordinates)); - } - - EnsureCoordinates(coordinates); - - int previousLatitude = 0; - int previousLongitude = 0; - - var sb = _pool.Get(); - - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = GetIntegerRepresentation(Latitude); - int longitude = GetIntegerRepresentation(Longitude); - - sb.Append(GetEncodedCharacters(latitude - previousLatitude).ToArray()); - sb.Append(GetEncodedCharacters(longitude - previousLongitude).ToArray()); - - previousLatitude = latitude; - previousLongitude = longitude; - } - - var result = sb.ToString(); - - _pool.Return(sb); - - return result; - } - - private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) { - var invalidCoordinates = coordinates - .Where(c => !CoordinateValidator.IsValid(c)); - - if (invalidCoordinates.Any()) { - throw new AggregateException( - invalidCoordinates - .Select(c => - new ArgumentOutOfRangeException() - ) - ); - } - } - - private static IEnumerable GetEncodedCharacters(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } - - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - private static int GetIntegerRepresentation(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - public static class CoordinateValidator { - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - } - - private class V3 { - /// - /// Method encodes coordinates to polyline encoded representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(); - } - - // Validate collection of coordinates - if (!TryValidate(coordinates, out var exceptions)) { - throw new AggregateException(exceptions); - } - - // Initializing local variables - int previousLatitude = 0; - int previousLongitude = 0; - var sb = new StringBuilder(coordinates.Count() * 4); - - // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(Latitude); - int longitude = Round(Longitude); - - sb.Append(GetSequence(latitude - previousLatitude).ToArray()); - sb.Append(GetSequence(longitude - previousLongitude).ToArray()); - - previousLatitude = latitude; - previousLongitude = longitude; - } - - return sb.ToString(); - - #region Local functions - - bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) { - exceptions = new List(collection.Count()); - - foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } - } - - return !exceptions.GetEnumerator().MoveNext(); - } - - int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - IEnumerable GetSequence(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } - - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - #endregion - } - - public static class CoordinateValidator { - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - /// - /// Performs latitude validation - /// - /// Latitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - /// - /// Performs longitude validation - /// - /// Longitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - - public class CoordinateValidationException(double latitude, double longitude) - : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { - public double Latitude { get; } - - public double Longitude { get; } - } - } - - internal class For { - public static void Loop(int count, Action action) { - for (int i = 0; i < count; i++) { - action.Invoke(); - } - } - } - } -} diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj index 21fedb5b..d1fa254a 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj @@ -7,6 +7,7 @@ enable enable true + en @@ -14,11 +15,7 @@ - All - latest - true - true - true + false @@ -26,4 +23,8 @@ + + + + diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs new file mode 100644 index 00000000..0b23a654 --- /dev/null +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs @@ -0,0 +1,578 @@ +namespace PolylineAlgorithm.Implementation.Benchmarks { + using BenchmarkDotNet.Attributes; + using BenchmarkDotNet.Engines; + using PolylineAlgorithm.Internal; + using System; + using System.Runtime.CompilerServices; + + [MemoryDiagnoser] + [RankColumn] + [Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.Declared)] + public class PolylineDecoderBenchmark { + private readonly Consumer _consumer = new(); + public static IEnumerable Polylines() { + yield return "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; + yield return "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; + yield return "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"; + } + + [Benchmark(Baseline = true)] + [ArgumentsSource(nameof(Polylines))] + public void Decode_Current(string polyline) => Current.Decode(polyline).Consume(_consumer); + + [Benchmark] + [ArgumentsSource(nameof(Polylines))] + public void Decode_V1(string polyline) => V1.Decode(polyline).Consume(_consumer); + + [Benchmark] + [ArgumentsSource(nameof(Polylines))] + public void Decode_V2(string polyline) => V2.Decode(polyline).Consume(_consumer); + + [Benchmark] + [ArgumentsSource(nameof(Polylines))] + public void Decode_V3(string polyline) => V3.Decode(polyline).Consume(_consumer); + + [Benchmark] + [ArgumentsSource(nameof(Polylines))] + public void Decode_V4(string polyline) => V4.Decode(polyline.AsMemory()).Consume(_consumer); + + [Benchmark] + [ArgumentsSource(nameof(Polylines))] + public void Decode_V5(string polyline) => V5.Decode(polyline).Consume(_consumer); + + [Benchmark] + [ArgumentsSource(nameof(Polylines))] + public void Decode_V6(string polyline) => V6.Default.Decode(polyline).Consume(_consumer); + + private class Current { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + // Checking null and at least one character + if (polyline == null || polyline.Length == 0) { + throw new ArgumentException(String.Empty, nameof(polyline)); + } + + // Initialize local variables + int index = 0; + int latitude = 0; + int longitude = 0; + + // Looping through encoded polyline char array + while (index < polyline.Length) { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref latitude)) { + throw new InvalidOperationException(String.Empty); + } + + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref longitude)) { + throw new InvalidOperationException(String.Empty); + } + + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + + // Validating decoded coordinate. If not valid exception is thrown + if (!CoordinateValidator.IsValid(coordinate)) { + throw new InvalidOperationException(String.Empty); + } + + yield return coordinate; + } + } + + static bool TryCalculateNext(string polyline, ref int index, ref int value) { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; + + do { + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + static double GetCoordinate(int value) { + return Convert.ToDouble(value) / Constants.Precision; + } + } + + private class V1 { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + if (polyline is null || polyline.Length == 0) { + throw new ArgumentException(nameof(polyline)); + } + + int index = 0; + int latitude = 0; + int longitude = 0; + + var result = new List<(double Latitude, double Longitude)>(); + + while (index < polyline.Length) { + if (!TryCalculateNext(ref polyline, ref index, ref latitude)) { + throw new InvalidOperationException(); + } + + if (!TryCalculateNext(ref polyline, ref index, ref longitude)) { + throw new InvalidOperationException(); + } + + var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); + + if (!CoordinateValidator.IsValid(coordinate)) { + throw new InvalidOperationException(); + } + + result.Add(coordinate); + } + + return result; + } + + private static bool TryCalculateNext(ref string polyline, ref int index, ref int value) { + int chunk; + int sum = 0; + int shifter = 0; + + do { + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + private static double GetDoubleRepresentation(int value) { + return Convert.ToDouble(value) / Constants.Precision; + } + + public static class CoordinateValidator { + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + } + } + + private class V2 { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + if (polyline is null || polyline.Length == 0) { + throw new ArgumentException(nameof(polyline)); + } + + int offset = 0; + int latitude = 0; + int longitude = 0; + + while (offset < polyline.Length) { + if (!TryCalculateNext(ref polyline, ref offset, ref latitude)) { + throw new InvalidOperationException(); + } + + if (!TryCalculateNext(ref polyline, ref offset, ref longitude)) { + throw new InvalidOperationException(); + } + + var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); + + if (!CoordinateValidator.IsValid(coordinate)) { + throw new InvalidOperationException(); + } + + yield return (latitude, longitude); + } + } + + private static bool TryCalculateNext(ref string polyline, ref int offset, ref int value) { + int chunk; + int sum = 0; + int shifter = 0; + + do { + chunk = polyline[offset++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && offset < polyline.Length); + + if (offset >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + private static double GetDoubleRepresentation(int value) { + return value / Constants.Precision; + } + + public static class CoordinateValidator { + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + } + } + + private class V3 { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + // Checking null and at least one character + if (polyline == null || polyline.Length == 0) { + throw new ArgumentException(String.Empty, nameof(polyline)); + } + + // Initialize local variables + int index = 0; + int latitude = 0; + int longitude = 0; + + // Looping through encoded polyline char array + while (index < polyline.Length) { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref latitude)) { + throw new InvalidOperationException(String.Empty); + } + + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref longitude)) { + throw new InvalidOperationException(String.Empty); + } + + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + + // Validating decoded coordinate. If not valid exception is thrown + if (!CoordinateValidator.IsValid(coordinate)) { + throw new InvalidOperationException(String.Empty); + } + + yield return coordinate; + + #region Local functions + + static bool TryCalculateNext(string polyline, ref int index, ref int value) { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; + + do { + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + static double GetCoordinate(int value) { + return Convert.ToDouble(value) / Constants.Precision; + } + + #endregion + } + } + + /// + /// Performs coordinate validation + /// + internal static class CoordinateValidator { + #region Methods + + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + + #endregion + } + } + + private class V4 { + public static IEnumerable<(double Latitude, double Longitude)> Decode(ReadOnlyMemory polyline) { + // Checking null and at least one character + if (polyline.IsEmpty) { + throw new ArgumentException(String.Empty, nameof(polyline)); + } + + // Initialize local variable + int index = 0; + int latitude = 0; + int longitude = 0; + + // Looping through encoded polyline char array + while (index < polyline.Length) { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(ref polyline, ref index, ref latitude)) { + throw new InvalidOperationException(String.Empty); + } + + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(ref polyline, ref index, ref longitude)) { + throw new InvalidOperationException(String.Empty); + } + + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + + // Validating decoded coordinate. If not valid exception is thrown + if (!CoordinateValidator.IsValid(coordinate)) { + throw new InvalidOperationException(String.Empty); + } + + yield return coordinate; + } + + static bool TryCalculateNext(ref ReadOnlyMemory polyline, ref int index, ref int value) { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; + + do { + chunk = polyline.Span[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + static double GetCoordinate(int value) { + return Convert.ToDouble(value) / Constants.Precision; + } + } + + /// + /// Performs coordinate validation + /// + internal static class CoordinateValidator { + #region Methods + + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + + #endregion + } + } + + private class V5 { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + // Checking null and at least one character + if (polyline == null || polyline.Length == 0) { + throw new ArgumentException(String.Empty, nameof(polyline)); + } + + // Initialize local variable + ReadOnlyMemory memory = polyline.AsMemory(); + int index = 0; + int latitude = 0; + int longitude = 0; + + // Looping through encoded polyline char array + while (index < memory.Length) { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(ref memory, ref index, ref latitude)) { + throw new InvalidOperationException(String.Empty); + } + + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(ref memory, ref index, ref longitude)) { + throw new InvalidOperationException(String.Empty); + } + + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + + // Validating decoded coordinate. If not valid exception is thrown + if (!CoordinateValidator.IsValid(coordinate)) { + throw new InvalidOperationException(String.Empty); + } + + yield return coordinate; + } + + static bool TryCalculateNext(ref ReadOnlyMemory polyline, ref int index, ref int value) { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; + + do { + chunk = polyline.Span[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + static double GetCoordinate(int value) { + return Convert.ToDouble(value) / Constants.Precision; + } + } + + /// + /// Performs coordinate validation + /// + internal static class CoordinateValidator { + #region Methods + + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + + #endregion + } + } + + private class V6 { + public static V6 Default = new(); + public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + // Checking null and at least one character + if (polyline == null || polyline.Length == 0) { + throw new ArgumentException(String.Empty, nameof(polyline)); + } + + // Initialize local variables + int index = 0; + int latitude = 0; + int longitude = 0; + + // Looping through encoded polyline char array + while (index < polyline.Length) { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref latitude)) { + throw new InvalidOperationException(String.Empty); + } + + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref longitude)) { + throw new InvalidOperationException(String.Empty); + } + + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + + // Validating decoded coordinate. If not valid exception is thrown + if (!CoordinateValidator.IsValid(coordinate)) { + throw new InvalidOperationException(String.Empty); + } + + yield return coordinate; + } + } + + private bool TryCalculateNext(string polyline, ref int index, ref int value) { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; + + do { + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + private double GetCoordinate(int value) { + return Convert.ToDouble(value) / Constants.Precision; + } + } + } +} diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs new file mode 100644 index 00000000..a792d856 --- /dev/null +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs @@ -0,0 +1,773 @@ +namespace PolylineAlgorithm.Implementation.Benchmarks { + using BenchmarkDotNet.Attributes; + using BenchmarkDotNet.Engines; + using Microsoft.Extensions.ObjectPool; + using System.Collections.Generic; + using System.Text; + + [MemoryDiagnoser] + [RankColumn] + [Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.Declared)] + public class PolylineEncoderBenchmark { + public IEnumerable<(int, IEnumerable<(double, double)> coordinates)> Coordinates() { + yield return (1, new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) }); + yield return (2, new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }); + yield return (3, new[] { (60.81071, -121.40005), (70.05664, -38.43130), (37.52379, -84.83755), (41.85003, 26.25620), (68.04709, 110.63120), (61.48922, 50.16245), (-4.46018, -58.11880), (-32.16061, -3.27505), (-50.89185, -55.30630), (-28.52070, 90.94370), (35.26009, 93.75620), (54.83622, 128.91245), (1.16022, 37.50620), (-44.26398, -131.24380), (-33.34325, 154.22495), (-59.65879, 90.94370), (-62.38215, 0.94370), (72.32117, 40.31870), (64.66910, 2.34995), (-61.04971, -84.83755), (77.10238, -91.86880), (-72.88859, -129.83755), (-69.24987, -24.36880), (77.41254, 119.06870), (-70.69409, 83.91245), (78.85650, 75.47495), (26.83989, 140.16245), (-24.75069, -108.74380), (30.53968, -145.30630), (79.12503, 145.78745), (-34.51006, 133.13120), (-73.29753, -60.93130), (-74.08712, 23.44370), (-76.57404, 100.78745), (-76.57404, 100.78745), (39.72082, 103.59995), (70.99412, 148.59995), (82.27591, 138.75620), (78.29964, -3.27505), (78.29964, -3.27505), (-8.65039, 47.34995) }); + } + + [Benchmark(Baseline = true)] + [ArgumentsSource(nameof(Coordinates))] + public string Encode_Current((int, IEnumerable<(double, double)> coordinates) value) => Current.Encode(value.coordinates); + + [Benchmark] + [ArgumentsSource(nameof(Coordinates))] + public string Encode_V1((int, IEnumerable<(double, double)> coordinates) value) => V1.Encode(value.coordinates); + + [Benchmark] + [ArgumentsSource(nameof(Coordinates))] + public string Encode_V2((int, IEnumerable<(double, double)> coordinates) value) => V2.Encode(value.coordinates); + + [Benchmark] + [ArgumentsSource(nameof(Coordinates))] + public string Encode_V3((int, IEnumerable<(double, double)> coordinates) value) => V3.Encode(value.coordinates); + + [Benchmark] + [ArgumentsSource(nameof(Coordinates))] + public string Encode_V4((int, IEnumerable<(double, double)> coordinates) value) => V4.Encode(value.coordinates); + + [Benchmark] + [ArgumentsSource(nameof(Coordinates))] + public string Encode_V5((int, IEnumerable<(double, double)> coordinates) value) => V5.Encode(value.coordinates); + + [Benchmark] + [ArgumentsSource(nameof(Coordinates))] + public string Encode_V6((int, IEnumerable<(double, double)> coordinates) value) => V6.Default.Encode(value.coordinates); + + private class Current { + /// + /// Method encodes coordinates to polyline encoded representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null or empty enumerable + /// If one or more coordinate is out of range + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { + throw new ArgumentException(); + } + + int count = coordinates.Count(); + ICollection exceptions = new List(count); + + // Validate collection of coordinates + if (!TryValidate(coordinates, ref exceptions)) { + throw new AggregateException(exceptions); + } + + // Initializing local variables + int index = 0; + Memory buffer = new char[count * 12]; + int previousLatitude = 0; + int previousLongitude = 0; + + // Looping over coordinates and building encoded result + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = Round(Latitude); + int longitude = Round(Longitude); + + WriteNext(ref buffer, ref index, ref latitude, ref previousLatitude); + WriteNext(ref buffer, ref index, ref longitude, ref previousLongitude); + } + + return buffer[..index].ToString(); + + #region Local functions + + static bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); + } + } + + return exceptions.Count == 0; + } + + static int Round(double value) { + return (int)Math.Round(value * Constants.Precision); + } + + static void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { + int value = current - previous; + int shifted = value << 1; + + if (value < 0) { + shifted = ~shifted; + } + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) { + buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + rem >>= Constants.ShiftLength; + index++; + } + + buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); + + index++; + + previous = current; + } + #endregion + } + + public static class CoordinateValidator { + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + /// + /// Performs latitude validation + /// + /// Latitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + /// + /// Performs longitude validation + /// + /// Longitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + } + + public class CoordinateValidationException(double latitude, double longitude) + : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { + public double Latitude { get; } + + public double Longitude { get; } + } + } + + private class V1 { + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates is null || !coordinates.Any()) { + throw new ArgumentException(nameof(coordinates)); + } + + EnsureCoordinates(coordinates); + + int lastLatitude = 0; + int lastLongitude = 0; + var sb = new StringBuilder(); + + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = GetIntegerRepresentation(Latitude); + int longitude = GetIntegerRepresentation(Longitude); + + sb.Append(GetEncodedCharacters(latitude - lastLatitude).ToArray()); + sb.Append(GetEncodedCharacters(longitude - lastLongitude).ToArray()); + + lastLatitude = latitude; + lastLongitude = longitude; + } + + return sb.ToString(); + } + + private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) { + var invalidCoordinates = coordinates + .Where(c => !CoordinateValidator.IsValid(c)); + + if (invalidCoordinates.Any()) { + throw new AggregateException( + invalidCoordinates + .Select(c => + new ArgumentOutOfRangeException() + ) + ); + } + } + + private static IEnumerable GetEncodedCharacters(int value) { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + + rem >>= Constants.ShiftLength; + } + + yield return (char)(rem + Constants.ASCII.QuestionMark); + } + + private static int GetIntegerRepresentation(double value) { + return (int)Math.Round(value * Constants.Precision); + } + + public static class CoordinateValidator { + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + } + } + + private class V2 { + private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, int.MaxValue); + + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates is null || !coordinates.Any()) { + throw new ArgumentException(nameof(coordinates)); + } + + EnsureCoordinates(coordinates); + + int previousLatitude = 0; + int previousLongitude = 0; + + var sb = _pool.Get(); + + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = GetIntegerRepresentation(Latitude); + int longitude = GetIntegerRepresentation(Longitude); + + sb.Append(GetEncodedCharacters(latitude - previousLatitude).ToArray()); + sb.Append(GetEncodedCharacters(longitude - previousLongitude).ToArray()); + + previousLatitude = latitude; + previousLongitude = longitude; + } + + var result = sb.ToString(); + + _pool.Return(sb); + + return result; + } + + private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) { + var invalidCoordinates = coordinates + .Where(c => !CoordinateValidator.IsValid(c)); + + if (invalidCoordinates.Any()) { + throw new AggregateException( + invalidCoordinates + .Select(c => + new ArgumentOutOfRangeException() + ) + ); + } + } + + private static IEnumerable GetEncodedCharacters(int value) { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + + rem >>= Constants.ShiftLength; + } + + yield return (char)(rem + Constants.ASCII.QuestionMark); + } + + private static int GetIntegerRepresentation(double value) { + return (int)Math.Round(value * Constants.Precision); + } + + public static class CoordinateValidator { + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + } + } + + private class V3 { + /// + /// Method encodes coordinates to polyline encoded representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null or empty enumerable + /// If one or more coordinate is out of range + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { + throw new ArgumentException(); + } + + // Validate collection of coordinates + if (!TryValidate(coordinates, out var exceptions)) { + throw new AggregateException(exceptions); + } + + // Initializing local variables + int previousLatitude = 0; + int previousLongitude = 0; + var sb = new StringBuilder(coordinates.Count() * 4); + + // Looping over coordinates and building encoded result + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = Round(Latitude); + int longitude = Round(Longitude); + + sb.Append(GetSequence(latitude - previousLatitude).ToArray()); + sb.Append(GetSequence(longitude - previousLongitude).ToArray()); + + previousLatitude = latitude; + previousLongitude = longitude; + } + + return sb.ToString(); + + #region Local functions + + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) { + exceptions = new List(collection.Count()); + + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); + } + } + + return !exceptions.GetEnumerator().MoveNext(); + } + + int Round(double value) { + return (int)Math.Round(value * Constants.Precision); + } + + IEnumerable GetSequence(int value) { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + + rem >>= Constants.ShiftLength; + } + + yield return (char)(rem + Constants.ASCII.QuestionMark); + } + + #endregion + } + + public static class CoordinateValidator { + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + /// + /// Performs latitude validation + /// + /// Latitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + /// + /// Performs longitude validation + /// + /// Longitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + } + + public class CoordinateValidationException(double latitude, double longitude) + : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { + public double Latitude { get; } + + public double Longitude { get; } + } + } + + private class V4 { + private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); + + /// + /// Method encodes coordinates to polyline encoded representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null or empty enumerable + /// If one or more coordinate is out of range + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { + throw new ArgumentException(); + } + + int count = coordinates.Count(); + ICollection exceptions = new List(count); + + // Validate collection of coordinates + if (!TryValidate(coordinates, ref exceptions)) { + throw new AggregateException(exceptions); + } + + // Initializing local variables + int previousLatitude = 0; + int previousLongitude = 0; + var sb = _pool.Get(); + + // Looping over coordinates and building encoded result + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = Round(Latitude); + int longitude = Round(Longitude); + + sb.Append(GetSequence(latitude - previousLatitude).ToArray()); + sb.Append(GetSequence(longitude - previousLongitude).ToArray()); + + previousLatitude = latitude; + previousLongitude = longitude; + } + + return sb.ToString(); + + #region Local functions + + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); + } + } + + return exceptions.Count == 0; + } + + int Round(double value) { + return (int)Math.Round(value * Constants.Precision); + } + + IEnumerable GetSequence(int value) { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + + rem >>= Constants.ShiftLength; + } + + yield return (char)(rem + Constants.ASCII.QuestionMark); + } + + #endregion + } + + public static class CoordinateValidator { + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + /// + /// Performs latitude validation + /// + /// Latitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + /// + /// Performs longitude validation + /// + /// Longitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + } + + public class CoordinateValidationException(double latitude, double longitude) + : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { + public double Latitude { get; } + + public double Longitude { get; } + } + } + + private class V5 { + private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); + + /// + /// Method encodes coordinates to polyline encoded representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null or empty enumerable + /// If one or more coordinate is out of range + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { + throw new ArgumentException(); + } + + int count = coordinates.Count(); + ICollection exceptions = new List(count); + + // Validate collection of coordinates + if (!TryValidate(coordinates, ref exceptions)) { + throw new AggregateException(exceptions); + } + + // Initializing local variables + int previousLatitude = 0; + int previousLongitude = 0; + var sb = _pool.Get(); + + // Looping over coordinates and building encoded result + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = Round(Latitude); + int longitude = Round(Longitude); + + sb.Append(GetSequence(latitude - previousLatitude).ToArray()); + sb.Append(GetSequence(longitude - previousLongitude).ToArray()); + + previousLatitude = latitude; + previousLongitude = longitude; + } + + return sb.ToString(); + + #region Local functions + + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); + } + } + + return exceptions.Count == 0; + } + + int Round(double value) { + return (int)Math.Round(value * Constants.Precision); + } + + IEnumerable GetSequence(int value) { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + + rem >>= Constants.ShiftLength; + } + + yield return (char)(rem + Constants.ASCII.QuestionMark); + } + + #endregion + } + + public static class CoordinateValidator { + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + /// + /// Performs latitude validation + /// + /// Latitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + /// + /// Performs longitude validation + /// + /// Longitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + } + + public class CoordinateValidationException(double latitude, double longitude) + : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { + public double Latitude { get; } + + public double Longitude { get; } + } + } + + private class V6 { + public static V6 Default = new(); + + /// + /// Method encodes coordinates to polyline encoded representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null or empty enumerable + /// If one or more coordinate is out of range + public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { + throw new ArgumentException(); + } + + int count = coordinates.Count(); + ICollection exceptions = new List(count); + + // Validate collection of coordinates + if (!TryValidate(coordinates, ref exceptions)) { + throw new AggregateException(exceptions); + } + + // Initializing local variables + int index = 0; + Memory buffer = new char[count * 12]; + int previousLatitude = 0; + int previousLongitude = 0; + + // Looping over coordinates and building encoded result + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = Round(Latitude); + int longitude = Round(Longitude); + + WriteNext(ref buffer, ref index, ref latitude, ref previousLatitude); + WriteNext(ref buffer, ref index, ref longitude, ref previousLongitude); + } + + return buffer[..index].ToString(); + } + + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); + } + } + + return exceptions.Count == 0; + } + + int Round(double value) { + return (int)Math.Round(value * Constants.Precision); + } + + void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { + int value = current - previous; + int shifted = value << 1; + + if (value < 0) { + shifted = ~shifted; + } + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) { + buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + rem >>= Constants.ShiftLength; + index++; + } + + buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); + + index++; + + previous = current; + } + + public static class CoordinateValidator { + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + /// + /// Performs latitude validation + /// + /// Latitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + /// + /// Performs longitude validation + /// + /// Longitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + } + + public class CoordinateValidationException(double latitude, double longitude) + : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { + public double Latitude { get; } + + public double Longitude { get; } + } + } + } +} diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs index 654105a6..e9f7ba3a 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs @@ -9,9 +9,9 @@ namespace PolylineAlgorithm.Implementation.Benchmarks { internal class Program { static void Main(string[] _) { BenchmarkRunner - .Run(); + .Run(); BenchmarkRunner - .Run(); + .Run(); } } } diff --git a/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj b/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj index 7b94773b..1d0f8821 100644 --- a/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj +++ b/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj @@ -14,6 +14,7 @@ true true true + false diff --git a/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs b/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs index 45e9359d..4abd2326 100644 --- a/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs @@ -5,7 +5,6 @@ namespace PolylineAlgorithm.DependencyInjection { using Microsoft.Extensions.DependencyInjection; - using PolylineAlgorithm.Encoding; public static class ServiceCollectionExtensions { /// @@ -14,8 +13,8 @@ public static class ServiceCollectionExtensions { /// Instance of /// nstance of public static IServiceCollection AddPolylineEncoder(this IServiceCollection services) { - return services - .AddSingleton(); + return services; + //.AddSingleton(); } /// diff --git a/src/PolylineAlgorithm/CoordinateValidationException.cs b/src/PolylineAlgorithm/CoordinateValidationException.cs index 34d164d5..0c348f09 100644 --- a/src/PolylineAlgorithm/CoordinateValidationException.cs +++ b/src/PolylineAlgorithm/CoordinateValidationException.cs @@ -1,7 +1,7 @@ namespace PolylineAlgorithm { using System; - public class CoordinateValidationException : Exception { + public sealed class CoordinateValidationException : Exception { public CoordinateValidationException(double latitude, double longitude) : base(string.Format(ExceptionMessageResource.CoordinateValidationExceptionCoordinateIsOutOfRangeErrorMessageFormat, latitude, longitude)) { } diff --git a/src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs b/src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs deleted file mode 100644 index 867ce823..00000000 --- a/src/PolylineAlgorithm/Encoding/DefaultPolylineEncoding.cs +++ /dev/null @@ -1,144 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -using PolylineAlgorithm.Internal; - -namespace PolylineAlgorithm.Encoding { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Runtime.CompilerServices; - using System.Text; - - public sealed class DefaultPolylineEncoding : IPolylineEncoding<(double Latitude, double Longitude)> { - private readonly CoordinateValidator _validator = new CoordinateValidator(); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public IEnumerable<(double Latitude, double Longitude)> Decode(string source) { - // Checking null and at least one character - if (source == null || source.Length == 0) { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(source)); - } - - // Initialize local variables - int index = 0; - int latitude = 0; - int longitude = 0; - - // Looping through encoded polyline char array - while (index < source.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(ref source, ref index, ref latitude)) { - throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); - } - - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(ref source, ref index, ref longitude)) { - throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); - } - - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - - // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); - } - - yield return coordinate; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(coordinates)); - } - - // Validate collection of coordinates - if (!TryValidate(coordinates, out var exceptions)) { - throw new AggregateException(exceptions); - } - - // Initializing local variables - int previousLatitude = 0; - int previousLongitude = 0; - var sb = new StringBuilder(coordinates.Count() * 5); - - // Looping over coordinates and building encoded result - foreach (var coordinate in coordinates) { - int latitude = Round(coordinate.Latitude); - int longitude = Round(coordinate.Longitude); - - sb.Append(GetSequence(latitude - previousLatitude).ToArray()); - sb.Append(GetSequence(longitude - previousLongitude).ToArray()); - - previousLatitude = latitude; - previousLongitude = longitude; - } - - return sb.ToString(); - } - - #region Private methods - - bool TryCalculateNext(ref string polyline, ref int index, ref int value) { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - double GetCoordinate(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } - - bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) { - exceptions = new List(collection.Count()); - - foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } - } - - return !exceptions.GetEnumerator().MoveNext(); - } - - int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - IEnumerable GetSequence(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } - - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - #endregion - } -} diff --git a/src/PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs b/src/PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs deleted file mode 100644 index 436b9279..00000000 --- a/src/PolylineAlgorithm/Encoding/IPolylineEncoding`1.cs +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Encoding { - using System.Collections.Generic; - - /// - /// Defines base interface for all polyline encodings - /// - /// Desired type used to decode to and encode from - public interface IPolylineEncoding { - /// - /// Method performs decoding from polyline encoded to - /// - /// Encoded coordinates - /// The - IEnumerable Decode(string source); - - /// - /// Method performs encoding from generic type to polyline encoded - /// - /// Coordinates to encode - /// Polyline encoded result - string Encode(IEnumerable source); - } -} diff --git a/src/PolylineAlgorithm/Encoding/PolylineEncoding`1.cs b/src/PolylineAlgorithm/Encoding/PolylineEncoding`1.cs deleted file mode 100644 index 60b6f281..00000000 --- a/src/PolylineAlgorithm/Encoding/PolylineEncoding`1.cs +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Encoding { - using System; - using System.Collections.Generic; - using System.Linq; - - /// /// - /// Defines base class for all polyline encodings - /// - /// - public abstract class PolylineEncoding : IPolylineEncoding { - /// - /// Method performs decode operation and coversion to desired type - /// - /// The - /// The - public IEnumerable Decode(string polyline) { - if (string.IsNullOrWhiteSpace(polyline)) { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(polyline)); - } - - return PolylineEncoder.Decode(polyline) - .Select(c => CreateResult(c.Latitude, c.Longitude)); - } - - /// - /// Method performs conversion to coordinate tuple and encode operation. - /// - /// The - /// The - public string Encode(IEnumerable source) { - if (source == null || !source.Any()) { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(source)); - } - - var coordinates = source.Select(s => GetCoordinate(s)); - - return PolylineEncoder.Encode(coordinates); - } - - /// - /// Method creates result from passed latitude and longitude arguments - /// - /// Latitude value - /// Longitude value - /// Returns created instance of - protected abstract T CreateResult(double latitude, double longitude); - - /// - /// The GetCoordinates - /// - /// The - /// The - protected abstract (double Latitude, double Longitude) GetCoordinate(T source); - } -} diff --git a/src/PolylineAlgorithm/ExceptionMessageResource.Designer.cs b/src/PolylineAlgorithm/ExceptionMessageResource.Designer.cs index b56ef89d..187e57ee 100644 --- a/src/PolylineAlgorithm/ExceptionMessageResource.Designer.cs +++ b/src/PolylineAlgorithm/ExceptionMessageResource.Designer.cs @@ -69,6 +69,15 @@ internal static string AggregateExceptionCoordinatesAreInvalidErrorMessage { } } + /// + /// Looks up a localized string similar to Argument cannot be an empty enumerable.. + /// + internal static string ArgumentCannotBeEmptyEnumerable { + get { + return ResourceManager.GetString("ArgumentCannotBeEmptyEnumerable", resourceCulture); + } + } + /// /// Looks up a localized string similar to Argument cannot be null -or- empty char array.. /// diff --git a/src/PolylineAlgorithm/ExceptionMessageResource.resx b/src/PolylineAlgorithm/ExceptionMessageResource.resx index 04001b03..8eabe752 100644 --- a/src/PolylineAlgorithm/ExceptionMessageResource.resx +++ b/src/PolylineAlgorithm/ExceptionMessageResource.resx @@ -123,6 +123,9 @@ Argument cannot be null -or- empty char array. + + Argument cannot be an empty enumerable. + Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180. diff --git a/src/PolylineAlgorithm/Internal/CoordinateValidator.cs b/src/PolylineAlgorithm/Internal/CoordinateValidator.cs index 6614a464..4c91b9d1 100644 --- a/src/PolylineAlgorithm/Internal/CoordinateValidator.cs +++ b/src/PolylineAlgorithm/Internal/CoordinateValidator.cs @@ -1,7 +1,4 @@ namespace PolylineAlgorithm.Internal { - using System.Runtime.CompilerServices; - - /// /// Performs coordinate validation /// @@ -13,17 +10,14 @@ internal class CoordinateValidator { /// /// Coordinate to validate /// Returns validation result. If valid then true, otherwise false. - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsValid((double Latitude, double Longitude) coordinate) { return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsValidLatitude(double latitude) { return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsValidLongitude(double longitude) { return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } diff --git a/src/PolylineAlgorithm/Internal/PolylineDecoder.cs b/src/PolylineAlgorithm/Internal/PolylineDecoder.cs new file mode 100644 index 00000000..561c8250 --- /dev/null +++ b/src/PolylineAlgorithm/Internal/PolylineDecoder.cs @@ -0,0 +1,72 @@ +namespace PolylineAlgorithm.Internal; + +using System; +using System.Collections.Generic; + +public sealed class PolylineDecoder { + + /// + /// Method decodes polyline encoded representation to coordinates. + /// + /// Encoded polyline string to decode + /// Returns coordinates. + /// If polyline argument is null -or- empty char array. + /// If polyline representation is not in correct format. + public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + // Checking null and at least one character + if (polyline == null || polyline.Length == 0) { + throw new ArgumentException(string.Empty, nameof(polyline)); + } + + // Initialize local variables + int index = 0; + int latitude = 0; + int longitude = 0; + + // Looping through encoded polyline char array + while (index < polyline.Length) { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref latitude)) { + throw new InvalidOperationException(string.Empty); + } + + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref longitude)) { + throw new InvalidOperationException(string.Empty); + } + + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + + // Validating decoded coordinate. If not valid exception is thrown + if (!CoordinateValidator.IsValid(coordinate)) { + throw new InvalidOperationException(string.Empty); + } + + yield return coordinate; + } + } + + private static bool TryCalculateNext(string polyline, ref int index, ref int value) { + // Initialize local variables + int chunk; + int sum = 0; + int shifter = 0; + + do { + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + private static double GetCoordinate(int value) { + return Convert.ToDouble(value) / Constants.Precision; + } +} \ No newline at end of file diff --git a/src/PolylineAlgorithm/Internal/PolylineEncoder.cs b/src/PolylineAlgorithm/Internal/PolylineEncoder.cs new file mode 100644 index 00000000..e43ca046 --- /dev/null +++ b/src/PolylineAlgorithm/Internal/PolylineEncoder.cs @@ -0,0 +1,95 @@ +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Internal { + using System; + using System.Collections.Generic; + using System.Linq; + + /// + /// Performs polyline algorithm decoding and encoding + /// + public sealed class PolylineEncoder { + /// + /// Method encodes coordinates to polyline encoded representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null + /// If coordinates parameter is empty + /// If one or more coordinate is out of range + public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates is null) { + throw new ArgumentNullException(nameof(coordinates)); + } + + if (!coordinates.GetEnumerator().MoveNext()) { + throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeEmptyEnumerable, nameof(coordinates)); + } + + int count = coordinates.Count(); + ICollection exceptions = new List(count); + + // Validate collection of coordinates + if (!TryValidate(coordinates, ref exceptions)) { + throw new AggregateException(ExceptionMessageResource.AggregateExceptionCoordinatesAreInvalidErrorMessage, exceptions); + } + + // Initializing local variables + int index = 0; + Memory buffer = new char[count * 12]; + int previousLatitude = 0; + int previousLongitude = 0; + + // Looping over coordinates and building encoded result + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = Round(Latitude); + int longitude = Round(Longitude); + + WriteNext(ref buffer, ref index, ref latitude, ref previousLatitude); + WriteNext(ref buffer, ref index, ref longitude, ref previousLongitude); + } + + return buffer[..index].ToString(); + } + + private static bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); + } + } + + return exceptions.Count == 0; + } + + private static int Round(double value) { + return (int)Math.Round(value * Constants.Precision); + } + + private static void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { + int value = current - previous; + int shifted = value << 1; + + if (value < 0) { + shifted = ~shifted; + } + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) { + buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + rem >>= Constants.ShiftLength; + index++; + } + + buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); + + index++; + + previous = current; + } + } +} diff --git a/src/PolylineAlgorithm/PolylineAlgorithm.csproj b/src/PolylineAlgorithm/PolylineAlgorithm.csproj index 1d029f7f..12c76d4f 100644 --- a/src/PolylineAlgorithm/PolylineAlgorithm.csproj +++ b/src/PolylineAlgorithm/PolylineAlgorithm.csproj @@ -15,6 +15,7 @@ true true true + false @@ -45,4 +46,10 @@ + + + <_Parameter1>PolylineAlgorithm.Implementation.Benchmarks + + + \ No newline at end of file diff --git a/src/PolylineAlgorithm/PolylineEncoder.cs b/src/PolylineAlgorithm/PolylineEncoder.cs deleted file mode 100644 index 89ba9f2a..00000000 --- a/src/PolylineAlgorithm/PolylineEncoder.cs +++ /dev/null @@ -1,159 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm { - using Microsoft.Extensions.ObjectPool; - using PolylineAlgorithm.Internal; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - - /// - /// Performs polyline algorithm decoding and encoding - /// - public static class PolylineEncoder { - private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); - private static readonly CoordinateValidator _validator = new CoordinateValidator(); - - /// - /// Method decodes polyline encoded representation to coordinates. - /// - /// Encoded polyline string to decode - /// Returns coordinates. - /// If polyline argument is null -or- empty char array. - /// If polyline representation is not in correct format. - public static IEnumerable<(double Latitude, double Longitude)> Decode(string source) { - // Checking null and at least one character - if (source == null || source.Length == 0) { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(source)); - } - - // Initialize local variables - int index = 0; - int latitude = 0; - int longitude = 0; - - // Looping through encoded polyline char array - while (index < source.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(source, ref index, ref latitude)) { - throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); - } - - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(source, ref index, ref longitude)) { - throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); - } - - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - - // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); - } - - yield return coordinate; - } - } - - /// - /// Method encodes coordinates to polyline encoded representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullOrEmpty, nameof(coordinates)); - } - - // Validate collection of coordinates - if (!TryValidate(coordinates, out var exceptions)) { - throw new AggregateException(exceptions); - } - - // Initializing local variables - int previousLatitude = 0; - int previousLongitude = 0; - var sb = _pool.Get(); - - // Looping over coordinates and building encoded result - foreach (var coordinate in coordinates) { - int latitude = Round(coordinate.Latitude); - int longitude = Round(coordinate.Longitude); - - sb.Append(GetSequence(latitude - previousLatitude).ToArray()); - sb.Append(GetSequence(longitude - previousLongitude).ToArray()); - - previousLatitude = latitude; - previousLongitude = longitude; - } - - return sb.ToString(); - } - - #region Private methods - - static bool TryCalculateNext(string polyline, ref int index, ref int value) { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - static double GetCoordinate(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } - - static bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) { - exceptions = new List(collection.Count()); - - foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } - } - - return !exceptions.GetEnumerator().MoveNext(); - } - - static int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - static IEnumerable GetSequence(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } - - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - #endregion - } -} diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs index 0e608465..1b7250b9 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs @@ -5,4 +5,3 @@ global using Microsoft.Extensions.DependencyInjection; global using Microsoft.VisualStudio.TestTools.UnitTesting; -global using PolylineAlgorithm.Encoding; \ No newline at end of file diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs index a029c39f..ff59dca9 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs @@ -9,18 +9,18 @@ namespace PolylineAlgorithm.DependencyInjection.Tests { public class ServiceCollectionExtensionsTests { private static IServiceCollection Services { get; } = new ServiceCollection().AddPolylineEncoder(); - [TestMethod] - public void Add_DefaultPolylineEncoder_Test() { - // Arrange - var provider = Services - .BuildServiceProvider(); + //[TestMethod] + //public void Add_DefaultPolylineEncoder_Test() { + // // Arrange + // var provider = Services + // .BuildServiceProvider(); - // Act - var encoder = provider - .GetRequiredService(); + // // Act + // var encoder = provider + // .GetRequiredService(); - // Assert - Assert.IsInstanceOfType(encoder); - } + // // Assert + // Assert.IsInstanceOfType(encoder); + //} } } \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs b/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs deleted file mode 100644 index e2bb390f..00000000 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithmTest.cs +++ /dev/null @@ -1,152 +0,0 @@ -// -// Copyright (c) Petr Šrámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Tests { - - /// - /// Defines the - /// - [TestClass] - [TestCategory(nameof(PolylineEncoder))] - public class PolylineAlgorithmTest { - /// - /// Method is testing method. Empty [] is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Decode_EmptyInput_ThrowsException() { - // Arrange - var emptyPolylineCharArray = Defaults.Polyline.Empty; - - // Act - void DecodeEmptyPolylineCharArray() { - PolylineEncoder.Decode(emptyPolylineCharArray).ToArray(); - } - - // Assert - Assert.ThrowsException(() => DecodeEmptyPolylineCharArray()); - } - - /// - /// Method is testing method. [] with invalid coordinates is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Decode_InvalidInput_ThrowsException() { - // Arrange - var invalidPolylineCharrArray = Defaults.Polyline.Invalid; - - // Act - void DecodeInvalidPolylineCharArray() { - PolylineEncoder.Decode(invalidPolylineCharrArray).ToArray(); - } - - // Assert - Assert.ThrowsException(() => DecodeInvalidPolylineCharArray()); - } - - /// - /// Method is testing method. is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Decode_NullInput_ThrowsException() { - // Arrange - var nullPolylineCharArray = (string)null!; - - // Act - void DecodeNullPolylineCharArray() { - PolylineEncoder.Decode(nullPolylineCharArray).ToArray(); - } - - // Assert - Assert.ThrowsException(() => DecodeNullPolylineCharArray()); - } - - /// - /// Method is testing method. [] with valid coordinates is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Decode_ValidInput_AreEquivalent() { - // Arrange - var validPolylineCharArray = Defaults.Polyline.Valid; - - // Act - var result = PolylineEncoder.Decode(validPolylineCharArray); - - // Assert - CollectionAssert.AreEquivalent(Defaults.Coordinate.Valid.ToList(), result.ToList()); - } - - /// - /// Method is testing method. Empty is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Encode_EmptyInput_ThrowsException() { - // Arrange - var emptyCoordinates = Defaults.Coordinate.Empty; - - // Act - void EncodeEmptyCoordinates() { - PolylineEncoder.Encode(emptyCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeEmptyCoordinates()); - } - - /// - /// The Encode_InvalidInput - /// - [TestMethod] - public void Encode_InvalidInput_ThrowsException() { - // Arrange - var invalidCoordinates = Defaults.Coordinate.Invalid; - - // Act - void EncodeInvalidCoordinates() { - PolylineEncoder.Encode(invalidCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeInvalidCoordinates()); - } - - /// - /// Method is testing method. is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Encode_NullInput_ThrowsException() { - // Arrange - var nullCoordinates = (IEnumerable<(double, double)>)null!; - - // Act - void EncodeNullCoordinates() { - PolylineEncoder.Encode(nullCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeNullCoordinates()); - } - - /// - /// The Encode_ValidInput - /// - [TestMethod] - public void Encode_ValidInput_AreEqual() { - // Arrange - var validCoordinates = Defaults.Coordinate.Valid; - - // Act - var result = PolylineEncoder.Encode(validCoordinates); - - // Assert - Assert.AreEqual(Defaults.Polyline.Valid, result); - } - } -} diff --git a/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs b/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs new file mode 100644 index 00000000..fcc8f6af --- /dev/null +++ b/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs @@ -0,0 +1,69 @@ +// +// Copyright (c) Petr Šrámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Tests { + using PolylineAlgorithm.Internal; + + /// + /// Defines the + /// + [TestClass] + [TestCategory(nameof(PolylineDecoder))] + public class PolylineDecoderTest { + private static PolylineDecoder Decoder { get; } = new PolylineDecoder(); + + /// + /// Method is testing method. Empty [] is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Decode_EmptyInput_ThrowsException() { + // Arrange + var emptyPolylineCharArray = Defaults.Polyline.Empty; + + // Act + void DecodeEmptyPolylineCharArray() { + Decoder.Decode(emptyPolylineCharArray).ToArray(); + } + + // Assert + Assert.ThrowsException(() => DecodeEmptyPolylineCharArray()); + } + + /// + /// Method is testing method. [] with invalid coordinates is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Decode_InvalidInput_ThrowsException() { + // Arrange + var invalidPolylineCharrArray = Defaults.Polyline.Invalid; + + // Act + void DecodeInvalidPolylineCharArray() { + Decoder.Decode(invalidPolylineCharrArray).ToArray(); + } + + // Assert + Assert.ThrowsException(() => DecodeInvalidPolylineCharArray()); + } + + /// + /// Method is testing method. [] with valid coordinates is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Decode_ValidInput_AreEquivalent() { + // Arrange + var validPolylineCharArray = Defaults.Polyline.Valid; + + // Act + var result = Decoder.Decode(validPolylineCharArray); + + // Assert + CollectionAssert.AreEquivalent(Defaults.Coordinate.Valid.ToList(), result.ToList()); + } + } +} diff --git a/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs b/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs new file mode 100644 index 00000000..5751ef94 --- /dev/null +++ b/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs @@ -0,0 +1,85 @@ +// +// Copyright (c) Petr Šrámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Tests { + using PolylineAlgorithm.Internal; + + /// + /// Defines the + /// + [TestClass] + [TestCategory(nameof(PolylineEncoder))] + public class PolylineEncoderTest { + private static PolylineEncoder Encoder { get; } = new PolylineEncoder(); + + /// + /// Method is testing method. Empty is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Encode_EmptyInput_ThrowsException() { + // Arrange + var emptyCoordinates = Defaults.Coordinate.Empty; + + // Act + void EncodeEmptyCoordinates() { + Encoder.Encode(emptyCoordinates); + } + + // Assert + Assert.ThrowsException(() => EncodeEmptyCoordinates()); + } + + /// + /// The Encode_InvalidInput + /// + [TestMethod] + public void Encode_InvalidInput_ThrowsException() { + // Arrange + var invalidCoordinates = Defaults.Coordinate.Invalid; + + // Act + void EncodeInvalidCoordinates() { + Encoder.Encode(invalidCoordinates); + } + + // Assert + Assert.ThrowsException(() => EncodeInvalidCoordinates()); + } + + /// + /// Method is testing method. is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Encode_NullInput_ThrowsException() { + // Arrange + var nullCoordinates = (IEnumerable<(double, double)>)null!; + + // Act + void EncodeNullCoordinates() { + Encoder.Encode(nullCoordinates); + } + + // Assert + Assert.ThrowsException(() => EncodeNullCoordinates()); + } + + /// + /// The Encode_ValidInput + /// + [TestMethod] + public void Encode_ValidInput_AreEqual() { + // Arrange + var validCoordinates = Defaults.Coordinate.Valid; + + // Act + var result = Encoder.Encode(validCoordinates); + + // Assert + Assert.AreEqual(Defaults.Polyline.Valid, result); + } + } +} From 83702aff1440f7655599f9d8efd2225ed2c51bf9 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Tue, 17 Dec 2024 20:31:52 +0100 Subject: [PATCH 030/352] fixes, cleanup --- .../PolylineAlgorithm.Benchmarks.csproj | 4 ---- .../PolylineDecoderBenchmark.cs | 9 ++++++--- .../PolylineEncoderBenchmark.cs | 4 +++- benchmarks/PolylineAlgorithm.Benchmarks/Program.cs | 2 ++ .../PolylineAlgorithm.Implementation.Benchmarks.csproj | 4 ---- .../PolylineEncoderBenchmark.cs | 1 - .../PolylineAlgorithm.DependencyInjection.csproj | 3 +-- src/PolylineAlgorithm/PolylineAlgorithm.csproj | 5 ----- 8 files changed, 12 insertions(+), 20 deletions(-) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj index 6bb7b296..5a8572fc 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj @@ -14,10 +14,6 @@ false - - false - - diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs index 09ddd776..165e2c85 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs @@ -6,12 +6,14 @@ namespace PolylineAlgorithm.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; + using BenchmarkDotNet.Order; using PolylineAlgorithm.Internal; [MemoryDiagnoser] [MarkdownExporter] + [Orderer(SummaryOrderPolicy.FastestToSlowest)] public class PolylineDecoderBenchmark { - private Consumer _consumer = new(); + private readonly Consumer _consumer = new(); public PolylineDecoder Decoder { get; set; } @@ -28,7 +30,8 @@ public void Setup() { [Benchmark] [ArgumentsSource(nameof(GetPolylines))] - public IEnumerable<(double, double)> Decode(string polyline) => Decoder - .Decode(polyline); + public void Decode(string polyline) => Decoder + .Decode(polyline) + .Consume(_consumer); } } diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs index e2d11a93..94d23243 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs @@ -6,12 +6,14 @@ namespace PolylineAlgorithm.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; + using BenchmarkDotNet.Order; using PolylineAlgorithm.Internal; [MemoryDiagnoser] [MarkdownExporter] + [Orderer(SummaryOrderPolicy.FastestToSlowest)] public class PolylineEncoderBenchmark { - private Consumer _consumer = new(); + private readonly Consumer _consumer = new(); public PolylineEncoder Encoder { get; set; } diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index 5ce7f56f..aeb0cbe8 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -10,6 +10,8 @@ internal class Program { static void Main(string[] _) { BenchmarkRunner .Run(); + BenchmarkRunner + .Run(); } } } diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj index d1fa254a..8f30bdbd 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj @@ -13,10 +13,6 @@ false - - - false - diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs index a792d856..47817b5f 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs @@ -1,6 +1,5 @@ namespace PolylineAlgorithm.Implementation.Benchmarks { using BenchmarkDotNet.Attributes; - using BenchmarkDotNet.Engines; using Microsoft.Extensions.ObjectPool; using System.Collections.Generic; using System.Text; diff --git a/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj b/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj index 1d0f8821..f4a94487 100644 --- a/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj +++ b/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj @@ -14,11 +14,10 @@ true true true - false - + diff --git a/src/PolylineAlgorithm/PolylineAlgorithm.csproj b/src/PolylineAlgorithm/PolylineAlgorithm.csproj index 12c76d4f..6314df9f 100644 --- a/src/PolylineAlgorithm/PolylineAlgorithm.csproj +++ b/src/PolylineAlgorithm/PolylineAlgorithm.csproj @@ -15,12 +15,7 @@ true true true - false - - - - From a4e627f9096ca33cc4636370882648d569063f89 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Tue, 17 Dec 2024 23:34:49 +0100 Subject: [PATCH 031/352] refactoring, cleanup --- .../PolylineDecoderBenchmark.cs | 5 +-- .../PolylineEncoderBenchmark.cs | 5 +-- .../PolylineDecoderBenchmark.cs.cs | 7 ++-- .../ServiceCollectionExtensions.cs | 18 ++------- .../{Internal => }/CoordinateValidator.cs | 18 ++++----- src/PolylineAlgorithm/ICoordinateValidator.cs | 5 +++ src/PolylineAlgorithm/IPolylineDecoder.cs | 7 ++++ src/PolylineAlgorithm/IPolylineEncoder.cs | 12 ++++++ .../{Internal => }/PolylineDecoder.cs | 10 ++--- .../{Internal => }/PolylineEncoder.cs | 12 ++++-- .../ServiceCollectionExtensionsTests.cs | 38 +++++++++++++------ .../CoordinateValidatorTest.cs | 5 ++- tests/PolylineAlgorithm.Tests/GlobalUsings.cs | 1 - .../PolylineDecoderTest.cs | 4 +- .../PolylineEncoderTest.cs | 4 +- 15 files changed, 88 insertions(+), 63 deletions(-) rename src/PolylineAlgorithm/{Internal => }/CoordinateValidator.cs (55%) create mode 100644 src/PolylineAlgorithm/ICoordinateValidator.cs create mode 100644 src/PolylineAlgorithm/IPolylineDecoder.cs create mode 100644 src/PolylineAlgorithm/IPolylineEncoder.cs rename src/PolylineAlgorithm/{Internal => }/PolylineDecoder.cs (88%) rename src/PolylineAlgorithm/{Internal => }/PolylineEncoder.cs (87%) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs index 165e2c85..af197f9a 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs @@ -7,7 +7,6 @@ namespace PolylineAlgorithm.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; using BenchmarkDotNet.Order; - using PolylineAlgorithm.Internal; [MemoryDiagnoser] [MarkdownExporter] @@ -15,7 +14,7 @@ namespace PolylineAlgorithm.Benchmarks { public class PolylineDecoderBenchmark { private readonly Consumer _consumer = new(); - public PolylineDecoder Decoder { get; set; } + public IPolylineDecoder Decoder { get; set; } public static IEnumerable GetPolylines() { yield return "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; @@ -25,7 +24,7 @@ public static IEnumerable GetPolylines() { [GlobalSetup] public void Setup() { - Decoder = new PolylineDecoder(); + Decoder = new PolylineDecoder(new CoordinateValidator()); } [Benchmark] diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs index 94d23243..e46b7f1e 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs @@ -7,7 +7,6 @@ namespace PolylineAlgorithm.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; using BenchmarkDotNet.Order; - using PolylineAlgorithm.Internal; [MemoryDiagnoser] [MarkdownExporter] @@ -15,7 +14,7 @@ namespace PolylineAlgorithm.Benchmarks { public class PolylineEncoderBenchmark { private readonly Consumer _consumer = new(); - public PolylineEncoder Encoder { get; set; } + public IPolylineEncoder Encoder { get; set; } public IEnumerable> GetCoordinates() { yield return new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) }; @@ -25,7 +24,7 @@ public class PolylineEncoderBenchmark { [GlobalSetup] public void Setup() { - Encoder = new PolylineEncoder(); + Encoder = new PolylineEncoder(new CoordinateValidator()); } [Benchmark] diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs index 0b23a654..cc9d9672 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs @@ -1,7 +1,7 @@ namespace PolylineAlgorithm.Implementation.Benchmarks { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; - using PolylineAlgorithm.Internal; + using PolylineAlgorithm; using System; using System.Runtime.CompilerServices; @@ -10,6 +10,7 @@ [Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.Declared)] public class PolylineDecoderBenchmark { private readonly Consumer _consumer = new(); + private readonly static CoordinateValidator _validator = new(); public static IEnumerable Polylines() { yield return "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; yield return "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; @@ -71,7 +72,7 @@ private class Current { var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) { + if (!_validator.IsValid(coordinate)) { throw new InvalidOperationException(String.Empty); } @@ -542,7 +543,7 @@ private class V6 { var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) { + if (!_validator.IsValid(coordinate)) { throw new InvalidOperationException(String.Empty); } diff --git a/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs b/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs index 4abd2326..adb9269c 100644 --- a/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs @@ -12,21 +12,11 @@ public static class ServiceCollectionExtensions { /// /// Instance of /// nstance of - public static IServiceCollection AddPolylineEncoder(this IServiceCollection services) { - return services; - //.AddSingleton(); - } - - /// - /// Registers singleton instance of to dependency container. - /// - /// Instance of - /// nstance of - public static IServiceCollection AddPolylineEncoder(this IServiceCollection services) - where TService : class - where TImplementation : class, TService { + public static IServiceCollection AddPolylineAlgorithm(this IServiceCollection services) { return services - .AddSingleton(); + .AddSingleton() + .AddSingleton() + .AddSingleton(); } } } diff --git a/src/PolylineAlgorithm/Internal/CoordinateValidator.cs b/src/PolylineAlgorithm/CoordinateValidator.cs similarity index 55% rename from src/PolylineAlgorithm/Internal/CoordinateValidator.cs rename to src/PolylineAlgorithm/CoordinateValidator.cs index 4c91b9d1..f222bc89 100644 --- a/src/PolylineAlgorithm/Internal/CoordinateValidator.cs +++ b/src/PolylineAlgorithm/CoordinateValidator.cs @@ -1,27 +1,25 @@ -namespace PolylineAlgorithm.Internal { +using PolylineAlgorithm.Internal; + +namespace PolylineAlgorithm { /// /// Performs coordinate validation /// - internal class CoordinateValidator { - #region Methods - + public sealed class CoordinateValidator : ICoordinateValidator { /// /// Performs coordinate validation /// /// Coordinate to validate /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + public bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(ref coordinate.Latitude) && IsValidLongitude(ref coordinate.Longitude); } - public static bool IsValidLatitude(double latitude) { + private static bool IsValidLatitude(ref readonly double latitude) { return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; } - public static bool IsValidLongitude(double longitude) { + private static bool IsValidLongitude(ref readonly double longitude) { return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } - - #endregion } } diff --git a/src/PolylineAlgorithm/ICoordinateValidator.cs b/src/PolylineAlgorithm/ICoordinateValidator.cs new file mode 100644 index 00000000..023023f8 --- /dev/null +++ b/src/PolylineAlgorithm/ICoordinateValidator.cs @@ -0,0 +1,5 @@ +namespace PolylineAlgorithm; + +public interface ICoordinateValidator { + bool IsValid((double Latitude, double Longitude) coordinate); +} \ No newline at end of file diff --git a/src/PolylineAlgorithm/IPolylineDecoder.cs b/src/PolylineAlgorithm/IPolylineDecoder.cs new file mode 100644 index 00000000..7f8fcb67 --- /dev/null +++ b/src/PolylineAlgorithm/IPolylineDecoder.cs @@ -0,0 +1,7 @@ +namespace PolylineAlgorithm; + +using System.Collections.Generic; + +public interface IPolylineDecoder { + IEnumerable<(double Latitude, double Longitude)> Decode(string polyline); +} \ No newline at end of file diff --git a/src/PolylineAlgorithm/IPolylineEncoder.cs b/src/PolylineAlgorithm/IPolylineEncoder.cs new file mode 100644 index 00000000..9a5b6d3d --- /dev/null +++ b/src/PolylineAlgorithm/IPolylineEncoder.cs @@ -0,0 +1,12 @@ +// +// Copyright (c) Petr Å rámek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; + +using System.Collections.Generic; + +public interface IPolylineEncoder { + string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates); +} \ No newline at end of file diff --git a/src/PolylineAlgorithm/Internal/PolylineDecoder.cs b/src/PolylineAlgorithm/PolylineDecoder.cs similarity index 88% rename from src/PolylineAlgorithm/Internal/PolylineDecoder.cs rename to src/PolylineAlgorithm/PolylineDecoder.cs index 561c8250..f0c37f5c 100644 --- a/src/PolylineAlgorithm/Internal/PolylineDecoder.cs +++ b/src/PolylineAlgorithm/PolylineDecoder.cs @@ -1,9 +1,9 @@ -namespace PolylineAlgorithm.Internal; +namespace PolylineAlgorithm; -using System; -using System.Collections.Generic; +using PolylineAlgorithm.Internal; -public sealed class PolylineDecoder { +public sealed class PolylineDecoder(ICoordinateValidator validator) : IPolylineDecoder { + public ICoordinateValidator Validator { get; } = validator ?? throw new ArgumentNullException(nameof(validator)); /// /// Method decodes polyline encoded representation to coordinates. @@ -38,7 +38,7 @@ public sealed class PolylineDecoder { var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) { + if (!Validator.IsValid(coordinate)) { throw new InvalidOperationException(string.Empty); } diff --git a/src/PolylineAlgorithm/Internal/PolylineEncoder.cs b/src/PolylineAlgorithm/PolylineEncoder.cs similarity index 87% rename from src/PolylineAlgorithm/Internal/PolylineEncoder.cs rename to src/PolylineAlgorithm/PolylineEncoder.cs index e43ca046..b5d99303 100644 --- a/src/PolylineAlgorithm/Internal/PolylineEncoder.cs +++ b/src/PolylineAlgorithm/PolylineEncoder.cs @@ -3,7 +3,9 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Internal { +using PolylineAlgorithm.Internal; + +namespace PolylineAlgorithm { using System; using System.Collections.Generic; using System.Linq; @@ -11,7 +13,9 @@ namespace PolylineAlgorithm.Internal { /// /// Performs polyline algorithm decoding and encoding /// - public sealed class PolylineEncoder { + public sealed class PolylineEncoder(ICoordinateValidator validator) : IPolylineEncoder { + public ICoordinateValidator Validator { get; } = validator ?? throw new ArgumentNullException(nameof(validator)); + /// /// Method encodes coordinates to polyline encoded representation /// @@ -55,9 +59,9 @@ public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinate return buffer[..index].ToString(); } - private static bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { + private bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { + if (!Validator.IsValid(item)) { exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); } } diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs index ff59dca9..45513140 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs @@ -7,20 +7,34 @@ namespace PolylineAlgorithm.DependencyInjection.Tests { [TestClass] public class ServiceCollectionExtensionsTests { - private static IServiceCollection Services { get; } = new ServiceCollection().AddPolylineEncoder(); + private static IServiceCollection Services { get; } = new ServiceCollection().AddPolylineAlgorithm(); - //[TestMethod] - //public void Add_DefaultPolylineEncoder_Test() { - // // Arrange - // var provider = Services - // .BuildServiceProvider(); + [TestMethod] + public void Add_PolylineEncoder_Test() { + // Arrange + var provider = Services + .BuildServiceProvider(); - // // Act - // var encoder = provider - // .GetRequiredService(); + // Act + var encoder = provider + .GetRequiredService(); - // // Assert - // Assert.IsInstanceOfType(encoder); - //} + // Assert + Assert.IsInstanceOfType(encoder); + } + + [TestMethod] + public void Add_PolylineDecoder_Test() { + // Arrange + var provider = Services + .BuildServiceProvider(); + + // Act + var decoder = provider + .GetRequiredService(); + + // Assert + Assert.IsInstanceOfType(decoder); + } } } \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs b/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs index 430d7155..dc3c768b 100644 --- a/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs +++ b/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs @@ -4,6 +4,7 @@ // namespace PolylineAlgorithm.Tests { + using PolylineAlgorithm; /// /// Defines the @@ -25,7 +26,7 @@ public void IsValid_InvalidInput_IsFalse() { foreach (var item in invalidCoordinateCollection) { // Arrange - var result = CoordinateValidator.IsValid(item); + var result = Validator.IsValid(item); // Assert Assert.IsFalse(result); @@ -42,7 +43,7 @@ public void IsValid_ValidInput_IsTrue() { foreach (var item in validCoordinateCollection) { // Arrange - var result = CoordinateValidator.IsValid(item); + var result = Validator.IsValid(item); // Assert Assert.IsTrue(result); diff --git a/tests/PolylineAlgorithm.Tests/GlobalUsings.cs b/tests/PolylineAlgorithm.Tests/GlobalUsings.cs index 597fed58..2b506c25 100644 --- a/tests/PolylineAlgorithm.Tests/GlobalUsings.cs +++ b/tests/PolylineAlgorithm.Tests/GlobalUsings.cs @@ -4,7 +4,6 @@ // global using Microsoft.VisualStudio.TestTools.UnitTesting; -global using PolylineAlgorithm.Internal; global using System; global using System.Collections.Generic; global using System.Linq; \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs b/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs index fcc8f6af..d18e98e3 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs +++ b/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs @@ -4,15 +4,13 @@ // namespace PolylineAlgorithm.Tests { - using PolylineAlgorithm.Internal; - /// /// Defines the /// [TestClass] [TestCategory(nameof(PolylineDecoder))] public class PolylineDecoderTest { - private static PolylineDecoder Decoder { get; } = new PolylineDecoder(); + private static PolylineDecoder Decoder { get; } = new PolylineDecoder(new CoordinateValidator()); /// /// Method is testing method. Empty [] is passed as parameter. diff --git a/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs b/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs index 5751ef94..f5ab7234 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs +++ b/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs @@ -4,15 +4,13 @@ // namespace PolylineAlgorithm.Tests { - using PolylineAlgorithm.Internal; - /// /// Defines the /// [TestClass] [TestCategory(nameof(PolylineEncoder))] public class PolylineEncoderTest { - private static PolylineEncoder Encoder { get; } = new PolylineEncoder(); + private static PolylineEncoder Encoder { get; } = new PolylineEncoder(new CoordinateValidator()); /// /// Method is testing method. Empty is passed as parameter. From 4234e27c84bee30bef18ce66f397e9def97df18a Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 15 Jan 2025 14:53:37 +0100 Subject: [PATCH 032/352] updated xml comments --- src/PolylineAlgorithm/PolylineDecoder.cs | 4 ++-- src/PolylineAlgorithm/PolylineEncoder.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/PolylineAlgorithm/PolylineDecoder.cs b/src/PolylineAlgorithm/PolylineDecoder.cs index f0c37f5c..dddee225 100644 --- a/src/PolylineAlgorithm/PolylineDecoder.cs +++ b/src/PolylineAlgorithm/PolylineDecoder.cs @@ -6,10 +6,10 @@ public sealed class PolylineDecoder(ICoordinateValidator validator) : IPolylineD public ICoordinateValidator Validator { get; } = validator ?? throw new ArgumentNullException(nameof(validator)); /// - /// Method decodes polyline encoded representation to coordinates. + /// Decodes polyline representation. /// /// Encoded polyline string to decode - /// Returns coordinates. + /// Returns coordinates /// If polyline argument is null -or- empty char array. /// If polyline representation is not in correct format. public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { diff --git a/src/PolylineAlgorithm/PolylineEncoder.cs b/src/PolylineAlgorithm/PolylineEncoder.cs index b5d99303..6cccdb3e 100644 --- a/src/PolylineAlgorithm/PolylineEncoder.cs +++ b/src/PolylineAlgorithm/PolylineEncoder.cs @@ -17,13 +17,13 @@ public sealed class PolylineEncoder(ICoordinateValidator validator) : IPolylineE public ICoordinateValidator Validator { get; } = validator ?? throw new ArgumentNullException(nameof(validator)); /// - /// Method encodes coordinates to polyline encoded representation + /// Encodes coordinates to polyline representation /// /// Coordinates to encode /// Polyline encoded representation - /// If coordinates parameter is null + /// If coordinates parameter is null /// If coordinates parameter is empty - /// If one or more coordinate is out of range + /// If one or more coordinate is out of valid range public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { if (coordinates is null) { throw new ArgumentNullException(nameof(coordinates)); From e06656634a0a03712ea3bcadf3c24b5a187af575 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 15 Jan 2025 15:04:33 +0100 Subject: [PATCH 033/352] extracted buffer size calculation to static local method --- src/PolylineAlgorithm/PolylineEncoder.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/PolylineAlgorithm/PolylineEncoder.cs b/src/PolylineAlgorithm/PolylineEncoder.cs index 6cccdb3e..a8992e96 100644 --- a/src/PolylineAlgorithm/PolylineEncoder.cs +++ b/src/PolylineAlgorithm/PolylineEncoder.cs @@ -43,7 +43,7 @@ public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinate // Initializing local variables int index = 0; - Memory buffer = new char[count * 12]; + Memory buffer = new char[GetSafeBufferSize(count)]; int previousLatitude = 0; int previousLongitude = 0; @@ -57,6 +57,10 @@ public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinate } return buffer[..index].ToString(); + + // Each coordinate consist of two values, each one is 4 or 5 chars long + // We use constant 12 = [2 * 6] to create safe buffer size + static int GetSafeBufferSize(int count) => count * 12; } private bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { From 36b1c5197c37576d7d520d69b00d22dbc5b4e820 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 15 Jan 2025 15:08:25 +0100 Subject: [PATCH 034/352] added Add_CoordinateValidator_Test method --- .../ServiceCollectionExtensionsTests.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs index 45513140..294a53ec 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs @@ -9,6 +9,20 @@ namespace PolylineAlgorithm.DependencyInjection.Tests { public class ServiceCollectionExtensionsTests { private static IServiceCollection Services { get; } = new ServiceCollection().AddPolylineAlgorithm(); + [TestMethod] + public void Add_CoordinateValidator_Test() { + // Arrange + var provider = Services + .BuildServiceProvider(); + + // Act + var encoder = provider + .GetRequiredService(); + + // Assert + Assert.IsInstanceOfType(encoder); + } + [TestMethod] public void Add_PolylineEncoder_Test() { // Arrange From b1606f5d651976981af9bb5b6ad2126d26f0b823 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 16 Jan 2025 23:36:30 +0100 Subject: [PATCH 035/352] refactoring, xml comments updated, code clean up --- .editorconfig | 105 +- PolylineAlgorithm.sln | 38 +- .../PolylineDecoderBenchmark.cs | 50 +- .../PolylineEncoderBenchmark.cs | 50 +- .../PolylineAlgorithm.Benchmarks/Program.cs | 20 +- .../Constants.cs | 2 +- .../PolylineDecoderBenchmark.cs.cs | 839 ++++++------ .../PolylineEncoderBenchmark.cs | 1169 +++++++++-------- .../Program.cs | 20 +- .../ContainerBuilderExtensions.cs | 31 + ...gorithm.DependencyInjection.Autofac.csproj | 27 + ...ithm.DependencyInjection.Microsoft.csproj} | 0 .../ServiceCollectionExtensions.cs | 25 + .../ServiceCollectionExtensions.cs | 22 - .../CoordinateValidationException.cs | 41 +- src/PolylineAlgorithm/CoordinateValidator.cs | 46 +- src/PolylineAlgorithm/ICoordinateValidator.cs | 15 +- src/PolylineAlgorithm/IPolylineDecoder.cs | 15 +- src/PolylineAlgorithm/IPolylineEncoder.cs | 10 +- src/PolylineAlgorithm/Internal/Constants.cs | 2 +- src/PolylineAlgorithm/PolylineDecoder.cs | 38 +- src/PolylineAlgorithm/PolylineEncoder.cs | 145 +- tests/Encoding/PolylineEncodingBaseTest.cs | 192 --- tests/Encoding/PolylineEncodingTest.cs | 51 - .../ContainerBuilderExtensionsTests.cs | 65 + .../GlobalSuppressions.cs | 8 + .../GlobalUsings.cs | 7 + ...m.DependencyInjection.Autofac.Tests.csproj | 42 + .../Properties/AssemblyInfo.cs | 2 +- .../GlobalSuppressions.cs | 8 + .../GlobalUsings.cs | 2 +- ...ependencyInjection.Microsoft.Tests.csproj} | 4 +- .../Properties/AssemblyInfo.cs | 6 + .../ServiceCollectionExtensionsTests.cs | 55 + .../GlobalSuppressions.cs | 8 - .../ServiceCollectionExtensionsTests.cs | 54 - .../CoordinateValidatorTest.cs | 86 +- tests/PolylineAlgorithm.Tests/Defaults.cs | 92 +- .../GlobalSuppressions.cs | 8 +- tests/PolylineAlgorithm.Tests/GlobalUsings.cs | 2 +- .../PolylineDecoderTest.cs | 100 +- .../PolylineEncoderTest.cs | 124 +- .../Properties/AssemblyInfo.cs | 2 +- tests/Validation/CoordinateValidatorTest.cs | 132 -- 44 files changed, 1889 insertions(+), 1871 deletions(-) create mode 100644 src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs create mode 100644 src/PolylineAlgorithm.DependencyInjection.Autofac/PolylineAlgorithm.DependencyInjection.Autofac.csproj rename src/{PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj => PolylineAlgorithm.DependencyInjection.Microsoft/PolylineAlgorithm.DependencyInjection.Microsoft.csproj} (100%) create mode 100644 src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs delete mode 100644 src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs delete mode 100644 tests/Encoding/PolylineEncodingBaseTest.cs delete mode 100644 tests/Encoding/PolylineEncodingTest.cs create mode 100644 tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs create mode 100644 tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalSuppressions.cs create mode 100644 tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalUsings.cs create mode 100644 tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests.csproj rename tests/{PolylineAlgorithm.DependencyInjection.Tests => PolylineAlgorithm.DependencyInjection.Autofac.Tests}/Properties/AssemblyInfo.cs (76%) create mode 100644 tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalSuppressions.cs rename tests/{PolylineAlgorithm.DependencyInjection.Tests => PolylineAlgorithm.DependencyInjection.Microsoft.Tests}/GlobalUsings.cs (81%) rename tests/{PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj => PolylineAlgorithm.DependencyInjection.Microsoft.Tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests.csproj} (89%) create mode 100644 tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/Properties/AssemblyInfo.cs create mode 100644 tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs delete mode 100644 tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalSuppressions.cs delete mode 100644 tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs delete mode 100644 tests/Validation/CoordinateValidatorTest.cs diff --git a/.editorconfig b/.editorconfig index f20597a1..cfa32c07 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1 +1,104 @@ -file_header_template = //\n// Copyright (c) Petr Šrámek. All rights reserved.\n// Licensed under the MIT License. See LICENSE file in the project root for full license information.\n// \ No newline at end of file +file_header_template = //\n// Copyright (c) Pete Sramek. All rights reserved.\n// Licensed under the MIT License. See LICENSE file in the project root for full license information.\n// +[*.cs] +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.private_or_internal_field_should_be_underscore_camel_case.severity = suggestion +dotnet_naming_rule.private_or_internal_field_should_be_underscore_camel_case.symbols = private_or_internal_field +dotnet_naming_rule.private_or_internal_field_should_be_underscore_camel_case.style = underscore_camel_case + +# Symbol specifications + +dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field +dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private, private_protected +dotnet_naming_symbols.private_or_internal_field.required_modifiers = + +# Naming styles + +dotnet_naming_style.underscore_camel_case.required_prefix = _ +dotnet_naming_style.underscore_camel_case.required_suffix = +dotnet_naming_style.underscore_camel_case.word_separator = +dotnet_naming_style.underscore_camel_case.capitalization = camel_case +csharp_indent_labels = one_less_than_current +csharp_using_directive_placement = inside_namespace:silent +csharp_prefer_simple_using_statement = false:suggestion +csharp_prefer_braces = true:silent +csharp_style_namespace_declarations = file_scoped:silent +csharp_style_prefer_method_group_conversion = false:silent +csharp_style_prefer_top_level_statements = false:silent +csharp_style_prefer_primary_constructors = true:suggestion +csharp_prefer_system_threading_lock = true:suggestion +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_lambdas = when_on_single_line:silent +csharp_style_expression_bodied_local_functions = when_on_single_line:silent + +[*.{cs,vb}] +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 4 +indent_size = 4 +end_of_line = crlf +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion diff --git a/PolylineAlgorithm.sln b/PolylineAlgorithm.sln index 99bae17f..41fcfe71 100644 --- a/PolylineAlgorithm.sln +++ b/PolylineAlgorithm.sln @@ -23,9 +23,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolylineAlgorithm.Benchmark EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolylineAlgorithm.Implementation.Benchmarks", "benchmarks\PolylineAlgorithm.Implementation.Benchmarks\PolylineAlgorithm.Implementation.Benchmarks.csproj", "{D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolylineAlgorithm.DependencyInjection", "src\PolylineAlgorithm.DependencyInjection\PolylineAlgorithm.DependencyInjection.csproj", "{0F07B56B-6D9A-4410-BCAB-C6A460C1E44E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolylineAlgorithm.DependencyInjection.Microsoft.Tests", "tests\PolylineAlgorithm.DependencyInjection.Microsoft.Tests\PolylineAlgorithm.DependencyInjection.Microsoft.Tests.csproj", "{B4FD710A-E5B8-4467-8D0B-037A28132047}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolylineAlgorithm.DependencyInjection.Tests", "tests\PolylineAlgorithm.DependencyInjection.Tests\PolylineAlgorithm.DependencyInjection.Tests.csproj", "{9DC1BAD9-60DD-414D-BE88-E181D887A267}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolylineAlgorithm.DependencyInjection.Autofac.Tests", "tests\PolylineAlgorithm.DependencyInjection.Autofac.Tests\PolylineAlgorithm.DependencyInjection.Autofac.Tests.csproj", "{F9CFF4B1-C9AB-4F94-ADF4-B29925E1187E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolylineAlgorithm.DependencyInjection.Autofac", "src\PolylineAlgorithm.DependencyInjection.Autofac\PolylineAlgorithm.DependencyInjection.Autofac.csproj", "{9C1088DA-DBF7-4374-9775-C7613CCA98D8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolylineAlgorithm.DependencyInjection.Microsoft", "src\PolylineAlgorithm.DependencyInjection.Microsoft\PolylineAlgorithm.DependencyInjection.Microsoft.csproj", "{2B0061B3-7B80-4101-9FF0-AD513AE4C4E5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -49,14 +53,22 @@ Global {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}.Debug|Any CPU.Build.0 = Debug|Any CPU {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}.Release|Any CPU.ActiveCfg = Release|Any CPU {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}.Release|Any CPU.Build.0 = Release|Any CPU - {0F07B56B-6D9A-4410-BCAB-C6A460C1E44E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0F07B56B-6D9A-4410-BCAB-C6A460C1E44E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0F07B56B-6D9A-4410-BCAB-C6A460C1E44E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0F07B56B-6D9A-4410-BCAB-C6A460C1E44E}.Release|Any CPU.Build.0 = Release|Any CPU - {9DC1BAD9-60DD-414D-BE88-E181D887A267}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9DC1BAD9-60DD-414D-BE88-E181D887A267}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9DC1BAD9-60DD-414D-BE88-E181D887A267}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9DC1BAD9-60DD-414D-BE88-E181D887A267}.Release|Any CPU.Build.0 = Release|Any CPU + {B4FD710A-E5B8-4467-8D0B-037A28132047}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B4FD710A-E5B8-4467-8D0B-037A28132047}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B4FD710A-E5B8-4467-8D0B-037A28132047}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B4FD710A-E5B8-4467-8D0B-037A28132047}.Release|Any CPU.Build.0 = Release|Any CPU + {F9CFF4B1-C9AB-4F94-ADF4-B29925E1187E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9CFF4B1-C9AB-4F94-ADF4-B29925E1187E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9CFF4B1-C9AB-4F94-ADF4-B29925E1187E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9CFF4B1-C9AB-4F94-ADF4-B29925E1187E}.Release|Any CPU.Build.0 = Release|Any CPU + {9C1088DA-DBF7-4374-9775-C7613CCA98D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C1088DA-DBF7-4374-9775-C7613CCA98D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C1088DA-DBF7-4374-9775-C7613CCA98D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C1088DA-DBF7-4374-9775-C7613CCA98D8}.Release|Any CPU.Build.0 = Release|Any CPU + {2B0061B3-7B80-4101-9FF0-AD513AE4C4E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2B0061B3-7B80-4101-9FF0-AD513AE4C4E5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2B0061B3-7B80-4101-9FF0-AD513AE4C4E5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2B0061B3-7B80-4101-9FF0-AD513AE4C4E5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -66,8 +78,10 @@ Global {30324A08-AA42-425D-87DA-8F9C6AF60454} = {576FEFFC-B624-40C3-A8AF-4E5233802EA0} {9C7CBAD5-415B-4589-86E1-01C849F9C56C} = {33C03F16-4313-4579-87E6-65892AF21D7D} {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B} = {33C03F16-4313-4579-87E6-65892AF21D7D} - {0F07B56B-6D9A-4410-BCAB-C6A460C1E44E} = {51C886AF-D610-48A4-9D73-2DEB38742801} - {9DC1BAD9-60DD-414D-BE88-E181D887A267} = {576FEFFC-B624-40C3-A8AF-4E5233802EA0} + {B4FD710A-E5B8-4467-8D0B-037A28132047} = {576FEFFC-B624-40C3-A8AF-4E5233802EA0} + {F9CFF4B1-C9AB-4F94-ADF4-B29925E1187E} = {576FEFFC-B624-40C3-A8AF-4E5233802EA0} + {9C1088DA-DBF7-4374-9775-C7613CCA98D8} = {51C886AF-D610-48A4-9D73-2DEB38742801} + {2B0061B3-7B80-4101-9FF0-AD513AE4C4E5} = {51C886AF-D610-48A4-9D73-2DEB38742801} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {93A268DC-0947-4FBB-B495-DDAD4B013D82} diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs index af197f9a..2f3a76fd 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs @@ -1,36 +1,36 @@ // -// Copyright (c) Petr Å rámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Benchmarks { - using BenchmarkDotNet.Attributes; - using BenchmarkDotNet.Engines; - using BenchmarkDotNet.Order; +namespace PolylineAlgorithm.Benchmarks; - [MemoryDiagnoser] - [MarkdownExporter] - [Orderer(SummaryOrderPolicy.FastestToSlowest)] - public class PolylineDecoderBenchmark { - private readonly Consumer _consumer = new(); +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Order; - public IPolylineDecoder Decoder { get; set; } +[MemoryDiagnoser] +[MarkdownExporter] +[Orderer(SummaryOrderPolicy.FastestToSlowest)] +public class PolylineDecoderBenchmark { + private readonly Consumer _consumer = new(); - public static IEnumerable GetPolylines() { - yield return "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; - yield return "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; - yield return "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"; - } + public required IPolylineDecoder Decoder { get; set; } - [GlobalSetup] - public void Setup() { - Decoder = new PolylineDecoder(new CoordinateValidator()); - } + public static IEnumerable GetPolylines() { + yield return "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; + yield return "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; + yield return "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"; + } - [Benchmark] - [ArgumentsSource(nameof(GetPolylines))] - public void Decode(string polyline) => Decoder - .Decode(polyline) - .Consume(_consumer); + [GlobalSetup] + public void Setup() { + Decoder = new PolylineDecoder(new CoordinateValidator()); } + + [Benchmark] + [ArgumentsSource(nameof(GetPolylines))] + public void Decode(string polyline) => Decoder + .Decode(polyline) + .Consume(_consumer); } diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs index e46b7f1e..06bdaf83 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs @@ -1,36 +1,36 @@ // -// Copyright (c) Petr Å rámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Benchmarks { - using BenchmarkDotNet.Attributes; - using BenchmarkDotNet.Engines; - using BenchmarkDotNet.Order; +namespace PolylineAlgorithm.Benchmarks; - [MemoryDiagnoser] - [MarkdownExporter] - [Orderer(SummaryOrderPolicy.FastestToSlowest)] - public class PolylineEncoderBenchmark { - private readonly Consumer _consumer = new(); +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Order; - public IPolylineEncoder Encoder { get; set; } +[MemoryDiagnoser] +[MarkdownExporter] +[Orderer(SummaryOrderPolicy.FastestToSlowest)] +public class PolylineEncoderBenchmark { + private readonly Consumer _consumer = new(); - public IEnumerable> GetCoordinates() { - yield return new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) }; - yield return new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }; - yield return new[] { (60.81071, -121.40005), (70.05664, -38.43130), (37.52379, -84.83755), (41.85003, 26.25620), (68.04709, 110.63120), (61.48922, 50.16245), (-4.46018, -58.11880), (-32.16061, -3.27505), (-50.89185, -55.30630), (-28.52070, 90.94370), (35.26009, 93.75620), (54.83622, 128.91245), (1.16022, 37.50620), (-44.26398, -131.24380), (-33.34325, 154.22495), (-59.65879, 90.94370), (-62.38215, 0.94370), (72.32117, 40.31870), (64.66910, 2.34995), (-61.04971, -84.83755), (77.10238, -91.86880), (-72.88859, -129.83755), (-69.24987, -24.36880), (77.41254, 119.06870), (-70.69409, 83.91245), (78.85650, 75.47495), (26.83989, 140.16245), (-24.75069, -108.74380), (30.53968, -145.30630), (79.12503, 145.78745), (-34.51006, 133.13120), (-73.29753, -60.93130), (-74.08712, 23.44370), (-76.57404, 100.78745), (-76.57404, 100.78745), (39.72082, 103.59995), (70.99412, 148.59995), (82.27591, 138.75620), (78.29964, -3.27505), (78.29964, -3.27505), (-8.65039, 47.34995) }; - } + public required IPolylineEncoder Encoder { get; set; } - [GlobalSetup] - public void Setup() { - Encoder = new PolylineEncoder(new CoordinateValidator()); - } + public static IEnumerable> GetCoordinates() { + yield return new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) }; + yield return new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }; + yield return new[] { (60.81071, -121.40005), (70.05664, -38.43130), (37.52379, -84.83755), (41.85003, 26.25620), (68.04709, 110.63120), (61.48922, 50.16245), (-4.46018, -58.11880), (-32.16061, -3.27505), (-50.89185, -55.30630), (-28.52070, 90.94370), (35.26009, 93.75620), (54.83622, 128.91245), (1.16022, 37.50620), (-44.26398, -131.24380), (-33.34325, 154.22495), (-59.65879, 90.94370), (-62.38215, 0.94370), (72.32117, 40.31870), (64.66910, 2.34995), (-61.04971, -84.83755), (77.10238, -91.86880), (-72.88859, -129.83755), (-69.24987, -24.36880), (77.41254, 119.06870), (-70.69409, 83.91245), (78.85650, 75.47495), (26.83989, 140.16245), (-24.75069, -108.74380), (30.53968, -145.30630), (79.12503, 145.78745), (-34.51006, 133.13120), (-73.29753, -60.93130), (-74.08712, 23.44370), (-76.57404, 100.78745), (-76.57404, 100.78745), (39.72082, 103.59995), (70.99412, 148.59995), (82.27591, 138.75620), (78.29964, -3.27505), (78.29964, -3.27505), (-8.65039, 47.34995) }; + } - [Benchmark] - [ArgumentsSource(nameof(GetCoordinates))] - public void Encode(IEnumerable<(double, double)> coordinates) => Encoder - .Encode(coordinates) - .Consume(_consumer); + [GlobalSetup] + public void Setup() { + Encoder = new PolylineEncoder(new CoordinateValidator()); } + + [Benchmark] + [ArgumentsSource(nameof(GetCoordinates))] + public void Encode(IEnumerable<(double, double)> coordinates) => Encoder + .Encode(coordinates) + .Consume(_consumer); } diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index aeb0cbe8..b8578882 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -1,17 +1,17 @@ // -// Copyright (c) Petr Å rámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Benchmarks { - using BenchmarkDotNet.Running; +namespace PolylineAlgorithm.Benchmarks; - internal class Program { - static void Main(string[] _) { - BenchmarkRunner - .Run(); - BenchmarkRunner - .Run(); - } +using BenchmarkDotNet.Running; + +internal class Program { + static void Main(string[] _) { + BenchmarkRunner + .Run(); + BenchmarkRunner + .Run(); } } diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs index e2ed73ed..f9a36eed 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs @@ -1,5 +1,5 @@ // -// Copyright (c) Petr Å rámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs index cc9d9672..500fee2a 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs @@ -1,383 +1,297 @@ -namespace PolylineAlgorithm.Implementation.Benchmarks { - using BenchmarkDotNet.Attributes; - using BenchmarkDotNet.Engines; - using PolylineAlgorithm; - using System; - using System.Runtime.CompilerServices; - - [MemoryDiagnoser] - [RankColumn] - [Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.Declared)] - public class PolylineDecoderBenchmark { - private readonly Consumer _consumer = new(); - private readonly static CoordinateValidator _validator = new(); - public static IEnumerable Polylines() { - yield return "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; - yield return "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; - yield return "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"; - } - - [Benchmark(Baseline = true)] - [ArgumentsSource(nameof(Polylines))] - public void Decode_Current(string polyline) => Current.Decode(polyline).Consume(_consumer); - - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V1(string polyline) => V1.Decode(polyline).Consume(_consumer); - - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V2(string polyline) => V2.Decode(polyline).Consume(_consumer); - - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V3(string polyline) => V3.Decode(polyline).Consume(_consumer); - - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V4(string polyline) => V4.Decode(polyline.AsMemory()).Consume(_consumer); - - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V5(string polyline) => V5.Decode(polyline).Consume(_consumer); +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Implementation.Benchmarks; + +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; +using PolylineAlgorithm; +using System; +using System.Runtime.CompilerServices; + +[MemoryDiagnoser] +[RankColumn] +[Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.Declared)] +public class PolylineDecoderBenchmark { + private readonly Consumer _consumer = new(); + private readonly static CoordinateValidator _validator = new(); + public static IEnumerable Polylines() { + yield return "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; + yield return "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; + yield return "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"; + } - [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V6(string polyline) => V6.Default.Decode(polyline).Consume(_consumer); + [Benchmark(Baseline = true)] + [ArgumentsSource(nameof(Polylines))] + public void Decode_Current(string polyline) => Current.Decode(polyline).Consume(_consumer); - private class Current { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - // Checking null and at least one character - if (polyline == null || polyline.Length == 0) { - throw new ArgumentException(String.Empty, nameof(polyline)); - } + [Benchmark] + [ArgumentsSource(nameof(Polylines))] + public void Decode_V1(string polyline) => V1.Decode(polyline).Consume(_consumer); - // Initialize local variables - int index = 0; - int latitude = 0; - int longitude = 0; + [Benchmark] + [ArgumentsSource(nameof(Polylines))] + public void Decode_V2(string polyline) => V2.Decode(polyline).Consume(_consumer); - // Looping through encoded polyline char array - while (index < polyline.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref latitude)) { - throw new InvalidOperationException(String.Empty); - } + [Benchmark] + [ArgumentsSource(nameof(Polylines))] + public void Decode_V3(string polyline) => V3.Decode(polyline).Consume(_consumer); - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref longitude)) { - throw new InvalidOperationException(String.Empty); - } + [Benchmark] + [ArgumentsSource(nameof(Polylines))] + public void Decode_V4(string polyline) => V4.Decode(polyline.AsMemory()).Consume(_consumer); - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + [Benchmark] + [ArgumentsSource(nameof(Polylines))] + public void Decode_V5(string polyline) => V5.Decode(polyline).Consume(_consumer); - // Validating decoded coordinate. If not valid exception is thrown - if (!_validator.IsValid(coordinate)) { - throw new InvalidOperationException(String.Empty); - } + [Benchmark] + [ArgumentsSource(nameof(Polylines))] + public void Decode_V6(string polyline) => V6.Default.Decode(polyline).Consume(_consumer); - yield return coordinate; - } + private class Current { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + // Checking null and at least one character + if (polyline == null || polyline.Length == 0) { + throw new ArgumentException(String.Empty, nameof(polyline)); } - static bool TryCalculateNext(string polyline, ref int index, ref int value) { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; + // Initialize local variables + int index = 0; + int latitude = 0; + int longitude = 0; - do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + // Looping through encoded polyline char array + while (index < polyline.Length) { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref latitude)) { + throw new InvalidOperationException(String.Empty); + } - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref longitude)) { + throw new InvalidOperationException(String.Empty); + } - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - return true; - } + // Validating decoded coordinate. If not valid exception is thrown + if (!_validator.IsValid(coordinate)) { + throw new InvalidOperationException(String.Empty); + } - static double GetCoordinate(int value) { - return Convert.ToDouble(value) / Constants.Precision; + yield return coordinate; } } - private class V1 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - if (polyline is null || polyline.Length == 0) { - throw new ArgumentException(nameof(polyline)); - } - - int index = 0; - int latitude = 0; - int longitude = 0; + static bool TryCalculateNext(string polyline, ref int index, ref int value) { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; - var result = new List<(double Latitude, double Longitude)>(); + do { + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - while (index < polyline.Length) { - if (!TryCalculateNext(ref polyline, ref index, ref latitude)) { - throw new InvalidOperationException(); - } + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; - if (!TryCalculateNext(ref polyline, ref index, ref longitude)) { - throw new InvalidOperationException(); - } + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); - - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(); - } + return true; + } - result.Add(coordinate); - } + static double GetCoordinate(int value) { + return Convert.ToDouble(value) / Constants.Precision; + } + } - return result; + private class V1 { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + if (polyline is null || polyline.Length == 0) { + throw new ArgumentException(nameof(polyline)); } - private static bool TryCalculateNext(ref string polyline, ref int index, ref int value) { - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; + int index = 0; + int latitude = 0; + int longitude = 0; - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - private static double GetDoubleRepresentation(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } + var result = new List<(double Latitude, double Longitude)>(); - public static class CoordinateValidator { - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + while (index < polyline.Length) { + if (!TryCalculateNext(ref polyline, ref index, ref latitude)) { + throw new InvalidOperationException(); } - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + if (!TryCalculateNext(ref polyline, ref index, ref longitude)) { + throw new InvalidOperationException(); } - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - } + var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); - private class V2 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - if (polyline is null || polyline.Length == 0) { - throw new ArgumentException(nameof(polyline)); + if (!CoordinateValidator.IsValid(coordinate)) { + throw new InvalidOperationException(); } - int offset = 0; - int latitude = 0; - int longitude = 0; + result.Add(coordinate); + } - while (offset < polyline.Length) { - if (!TryCalculateNext(ref polyline, ref offset, ref latitude)) { - throw new InvalidOperationException(); - } + return result; + } - if (!TryCalculateNext(ref polyline, ref offset, ref longitude)) { - throw new InvalidOperationException(); - } + private static bool TryCalculateNext(ref string polyline, ref int index, ref int value) { + int chunk; + int sum = 0; + int shifter = 0; - var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); + do { + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(); - } + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; - yield return (latitude, longitude); - } - } - - private static bool TryCalculateNext(ref string polyline, ref int offset, ref int value) { - int chunk; - int sum = 0; - int shifter = 0; + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - do { - chunk = polyline[offset++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && offset < polyline.Length); + return true; + } - if (offset >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; + private static double GetDoubleRepresentation(int value) { + return Convert.ToDouble(value) / Constants.Precision; + } - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + public static class CoordinateValidator { + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } - return true; + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; } - private static double GetDoubleRepresentation(int value) { - return value / Constants.Precision; + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } + } + } - public static class CoordinateValidator { - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } + private class V2 { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + if (polyline is null || polyline.Length == 0) { + throw new ArgumentException(nameof(polyline)); + } - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } + int offset = 0; + int latitude = 0; + int longitude = 0; - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + while (offset < polyline.Length) { + if (!TryCalculateNext(ref polyline, ref offset, ref latitude)) { + throw new InvalidOperationException(); } - } - } - private class V3 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - // Checking null and at least one character - if (polyline == null || polyline.Length == 0) { - throw new ArgumentException(String.Empty, nameof(polyline)); + if (!TryCalculateNext(ref polyline, ref offset, ref longitude)) { + throw new InvalidOperationException(); } - // Initialize local variables - int index = 0; - int latitude = 0; - int longitude = 0; + var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); - // Looping through encoded polyline char array - while (index < polyline.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref latitude)) { - throw new InvalidOperationException(String.Empty); - } - - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref longitude)) { - throw new InvalidOperationException(String.Empty); - } + if (!CoordinateValidator.IsValid(coordinate)) { + throw new InvalidOperationException(); + } - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + yield return (latitude, longitude); + } + } - // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(String.Empty); - } + private static bool TryCalculateNext(ref string polyline, ref int offset, ref int value) { + int chunk; + int sum = 0; + int shifter = 0; - yield return coordinate; + do { + chunk = polyline[offset++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && offset < polyline.Length); - #region Local functions + if (offset >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; - static bool TryCalculateNext(string polyline, ref int index, ref int value) { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + return true; + } - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; + private static double GetDoubleRepresentation(int value) { + return value / Constants.Precision; + } - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + public static class CoordinateValidator { + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } - return true; - } + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } - static double GetCoordinate(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + } + } - #endregion - } + private class V3 { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + // Checking null and at least one character + if (polyline == null || polyline.Length == 0) { + throw new ArgumentException(String.Empty, nameof(polyline)); } - /// - /// Performs coordinate validation - /// - internal static class CoordinateValidator { - #region Methods - - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } + // Initialize local variables + int index = 0; + int latitude = 0; + int longitude = 0; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + // Looping through encoded polyline char array + while (index < polyline.Length) { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref latitude)) { + throw new InvalidOperationException(String.Empty); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref longitude)) { + throw new InvalidOperationException(String.Empty); } - #endregion - } - } + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - private class V4 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(ReadOnlyMemory polyline) { - // Checking null and at least one character - if (polyline.IsEmpty) { - throw new ArgumentException(String.Empty, nameof(polyline)); + // Validating decoded coordinate. If not valid exception is thrown + if (!CoordinateValidator.IsValid(coordinate)) { + throw new InvalidOperationException(String.Empty); } - // Initialize local variable - int index = 0; - int latitude = 0; - int longitude = 0; - - // Looping through encoded polyline char array - while (index < polyline.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(ref polyline, ref index, ref latitude)) { - throw new InvalidOperationException(String.Empty); - } - - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(ref polyline, ref index, ref longitude)) { - throw new InvalidOperationException(String.Empty); - } + yield return coordinate; - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - - // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(String.Empty); - } - - yield return coordinate; - } + #region Local functions - static bool TryCalculateNext(ref ReadOnlyMemory polyline, ref int index, ref int value) { + static bool TryCalculateNext(string polyline, ref int index, ref int value) { // Local variable initialization int chunk; int sum = 0; int shifter = 0; do { - chunk = polyline.Span[index++] - Constants.ASCII.QuestionMark; + chunk = polyline[index++] - Constants.ASCII.QuestionMark; sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; shifter += Constants.ShiftLength; } while (chunk >= Constants.ASCII.Space && index < polyline.Length); @@ -393,172 +307,173 @@ static bool TryCalculateNext(ref ReadOnlyMemory polyline, ref int index, r static double GetCoordinate(int value) { return Convert.ToDouble(value) / Constants.Precision; } + + #endregion } + } + + /// + /// Performs coordinate validation + /// + internal static class CoordinateValidator { + #region Methods /// /// Performs coordinate validation /// - internal static class CoordinateValidator { - #region Methods - - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } - #endregion + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } - } - private class V5 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - // Checking null and at least one character - if (polyline == null || polyline.Length == 0) { - throw new ArgumentException(String.Empty, nameof(polyline)); - } + #endregion + } + } - // Initialize local variable - ReadOnlyMemory memory = polyline.AsMemory(); - int index = 0; - int latitude = 0; - int longitude = 0; + private class V4 { + public static IEnumerable<(double Latitude, double Longitude)> Decode(ReadOnlyMemory polyline) { + // Checking null and at least one character + if (polyline.IsEmpty) { + throw new ArgumentException(String.Empty, nameof(polyline)); + } - // Looping through encoded polyline char array - while (index < memory.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(ref memory, ref index, ref latitude)) { - throw new InvalidOperationException(String.Empty); - } + // Initialize local variable + int index = 0; + int latitude = 0; + int longitude = 0; - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(ref memory, ref index, ref longitude)) { - throw new InvalidOperationException(String.Empty); - } + // Looping through encoded polyline char array + while (index < polyline.Length) { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(ref polyline, ref index, ref latitude)) { + throw new InvalidOperationException(String.Empty); + } - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(ref polyline, ref index, ref longitude)) { + throw new InvalidOperationException(String.Empty); + } - // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(String.Empty); - } + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - yield return coordinate; + // Validating decoded coordinate. If not valid exception is thrown + if (!CoordinateValidator.IsValid(coordinate)) { + throw new InvalidOperationException(String.Empty); } - static bool TryCalculateNext(ref ReadOnlyMemory polyline, ref int index, ref int value) { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; + yield return coordinate; + } - do { - chunk = polyline.Span[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + static bool TryCalculateNext(ref ReadOnlyMemory polyline, ref int index, ref int value) { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; + do { + chunk = polyline.Span[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; - return true; - } + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - static double GetCoordinate(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } + return true; + } + + static double GetCoordinate(int value) { + return Convert.ToDouble(value) / Constants.Precision; } + } + + /// + /// Performs coordinate validation + /// + internal static class CoordinateValidator { + #region Methods /// /// Performs coordinate validation /// - internal static class CoordinateValidator { - #region Methods - - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } - #endregion + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } - } - private class V6 { - public static V6 Default = new(); - public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - // Checking null and at least one character - if (polyline == null || polyline.Length == 0) { - throw new ArgumentException(String.Empty, nameof(polyline)); - } + #endregion + } + } - // Initialize local variables - int index = 0; - int latitude = 0; - int longitude = 0; + private class V5 { + public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + // Checking null and at least one character + if (polyline == null || polyline.Length == 0) { + throw new ArgumentException(String.Empty, nameof(polyline)); + } - // Looping through encoded polyline char array - while (index < polyline.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref latitude)) { - throw new InvalidOperationException(String.Empty); - } + // Initialize local variable + ReadOnlyMemory memory = polyline.AsMemory(); + int index = 0; + int latitude = 0; + int longitude = 0; - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref longitude)) { - throw new InvalidOperationException(String.Empty); - } + // Looping through encoded polyline char array + while (index < memory.Length) { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(ref memory, ref index, ref latitude)) { + throw new InvalidOperationException(String.Empty); + } - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(ref memory, ref index, ref longitude)) { + throw new InvalidOperationException(String.Empty); + } - // Validating decoded coordinate. If not valid exception is thrown - if (!_validator.IsValid(coordinate)) { - throw new InvalidOperationException(String.Empty); - } + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - yield return coordinate; + // Validating decoded coordinate. If not valid exception is thrown + if (!CoordinateValidator.IsValid(coordinate)) { + throw new InvalidOperationException(String.Empty); } + + yield return coordinate; } - private bool TryCalculateNext(string polyline, ref int index, ref int value) { + static bool TryCalculateNext(ref ReadOnlyMemory polyline, ref int index, ref int value) { // Local variable initialization int chunk; int sum = 0; int shifter = 0; do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; + chunk = polyline.Span[index++] - Constants.ASCII.QuestionMark; sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; shifter += Constants.ShiftLength; } while (chunk >= Constants.ASCII.Space && index < polyline.Length); @@ -571,9 +486,99 @@ private bool TryCalculateNext(string polyline, ref int index, ref int value) { return true; } - private double GetCoordinate(int value) { + static double GetCoordinate(int value) { return Convert.ToDouble(value) / Constants.Precision; } } + + /// + /// Performs coordinate validation + /// + internal static class CoordinateValidator { + #region Methods + + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + + #endregion + } + } + + private class V6 { + public static V6 Default = new(); + public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + // Checking null and at least one character + if (polyline == null || polyline.Length == 0) { + throw new ArgumentException(String.Empty, nameof(polyline)); + } + + // Initialize local variables + int index = 0; + int latitude = 0; + int longitude = 0; + + // Looping through encoded polyline char array + while (index < polyline.Length) { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref latitude)) { + throw new InvalidOperationException(String.Empty); + } + + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref longitude)) { + throw new InvalidOperationException(String.Empty); + } + + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + + // Validating decoded coordinate. If not valid exception is thrown + if (!_validator.IsValid(coordinate)) { + throw new InvalidOperationException(String.Empty); + } + + yield return coordinate; + } + } + + private bool TryCalculateNext(string polyline, ref int index, ref int value) { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; + + do { + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + private double GetCoordinate(int value) { + return Convert.ToDouble(value) / Constants.Precision; + } } } diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs index 47817b5f..f19ee966 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs @@ -1,772 +1,777 @@ -namespace PolylineAlgorithm.Implementation.Benchmarks { - using BenchmarkDotNet.Attributes; - using Microsoft.Extensions.ObjectPool; - using System.Collections.Generic; - using System.Text; - - [MemoryDiagnoser] - [RankColumn] - [Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.Declared)] - public class PolylineEncoderBenchmark { - public IEnumerable<(int, IEnumerable<(double, double)> coordinates)> Coordinates() { - yield return (1, new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) }); - yield return (2, new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }); - yield return (3, new[] { (60.81071, -121.40005), (70.05664, -38.43130), (37.52379, -84.83755), (41.85003, 26.25620), (68.04709, 110.63120), (61.48922, 50.16245), (-4.46018, -58.11880), (-32.16061, -3.27505), (-50.89185, -55.30630), (-28.52070, 90.94370), (35.26009, 93.75620), (54.83622, 128.91245), (1.16022, 37.50620), (-44.26398, -131.24380), (-33.34325, 154.22495), (-59.65879, 90.94370), (-62.38215, 0.94370), (72.32117, 40.31870), (64.66910, 2.34995), (-61.04971, -84.83755), (77.10238, -91.86880), (-72.88859, -129.83755), (-69.24987, -24.36880), (77.41254, 119.06870), (-70.69409, 83.91245), (78.85650, 75.47495), (26.83989, 140.16245), (-24.75069, -108.74380), (30.53968, -145.30630), (79.12503, 145.78745), (-34.51006, 133.13120), (-73.29753, -60.93130), (-74.08712, 23.44370), (-76.57404, 100.78745), (-76.57404, 100.78745), (39.72082, 103.59995), (70.99412, 148.59995), (82.27591, 138.75620), (78.29964, -3.27505), (78.29964, -3.27505), (-8.65039, 47.34995) }); - } - - [Benchmark(Baseline = true)] - [ArgumentsSource(nameof(Coordinates))] - public string Encode_Current((int, IEnumerable<(double, double)> coordinates) value) => Current.Encode(value.coordinates); - - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public string Encode_V1((int, IEnumerable<(double, double)> coordinates) value) => V1.Encode(value.coordinates); - - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public string Encode_V2((int, IEnumerable<(double, double)> coordinates) value) => V2.Encode(value.coordinates); - - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public string Encode_V3((int, IEnumerable<(double, double)> coordinates) value) => V3.Encode(value.coordinates); - - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public string Encode_V4((int, IEnumerable<(double, double)> coordinates) value) => V4.Encode(value.coordinates); - - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public string Encode_V5((int, IEnumerable<(double, double)> coordinates) value) => V5.Encode(value.coordinates); - - [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public string Encode_V6((int, IEnumerable<(double, double)> coordinates) value) => V6.Default.Encode(value.coordinates); +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Implementation.Benchmarks; + +using BenchmarkDotNet.Attributes; +using Microsoft.Extensions.ObjectPool; +using System.Collections.Generic; +using System.Text; + +[MemoryDiagnoser] +[RankColumn] +[Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.Declared)] +public class PolylineEncoderBenchmark { + public IEnumerable<(int, IEnumerable<(double, double)> coordinates)> Coordinates() { + yield return (1, new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) }); + yield return (2, new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }); + yield return (3, new[] { (60.81071, -121.40005), (70.05664, -38.43130), (37.52379, -84.83755), (41.85003, 26.25620), (68.04709, 110.63120), (61.48922, 50.16245), (-4.46018, -58.11880), (-32.16061, -3.27505), (-50.89185, -55.30630), (-28.52070, 90.94370), (35.26009, 93.75620), (54.83622, 128.91245), (1.16022, 37.50620), (-44.26398, -131.24380), (-33.34325, 154.22495), (-59.65879, 90.94370), (-62.38215, 0.94370), (72.32117, 40.31870), (64.66910, 2.34995), (-61.04971, -84.83755), (77.10238, -91.86880), (-72.88859, -129.83755), (-69.24987, -24.36880), (77.41254, 119.06870), (-70.69409, 83.91245), (78.85650, 75.47495), (26.83989, 140.16245), (-24.75069, -108.74380), (30.53968, -145.30630), (79.12503, 145.78745), (-34.51006, 133.13120), (-73.29753, -60.93130), (-74.08712, 23.44370), (-76.57404, 100.78745), (-76.57404, 100.78745), (39.72082, 103.59995), (70.99412, 148.59995), (82.27591, 138.75620), (78.29964, -3.27505), (78.29964, -3.27505), (-8.65039, 47.34995) }); + } - private class Current { - /// - /// Method encodes coordinates to polyline encoded representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(); - } + [Benchmark(Baseline = true)] + [ArgumentsSource(nameof(Coordinates))] + public string Encode_Current((int, IEnumerable<(double, double)> coordinates) value) => Current.Encode(value.coordinates); + + [Benchmark] + [ArgumentsSource(nameof(Coordinates))] + public string Encode_V1((int, IEnumerable<(double, double)> coordinates) value) => V1.Encode(value.coordinates); + + [Benchmark] + [ArgumentsSource(nameof(Coordinates))] + public string Encode_V2((int, IEnumerable<(double, double)> coordinates) value) => V2.Encode(value.coordinates); + + [Benchmark] + [ArgumentsSource(nameof(Coordinates))] + public string Encode_V3((int, IEnumerable<(double, double)> coordinates) value) => V3.Encode(value.coordinates); + + [Benchmark] + [ArgumentsSource(nameof(Coordinates))] + public string Encode_V4((int, IEnumerable<(double, double)> coordinates) value) => V4.Encode(value.coordinates); + + [Benchmark] + [ArgumentsSource(nameof(Coordinates))] + public string Encode_V5((int, IEnumerable<(double, double)> coordinates) value) => V5.Encode(value.coordinates); + + [Benchmark] + [ArgumentsSource(nameof(Coordinates))] + public string Encode_V6((int, IEnumerable<(double, double)> coordinates) value) => V6.Default.Encode(value.coordinates); + + private class Current { + /// + /// Method encodes coordinates to polyline encoded representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null or empty enumerable + /// If one or more coordinate is out of range + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { + throw new ArgumentException(); + } - int count = coordinates.Count(); - ICollection exceptions = new List(count); + int count = coordinates.Count(); + ICollection exceptions = new List(count); - // Validate collection of coordinates - if (!TryValidate(coordinates, ref exceptions)) { - throw new AggregateException(exceptions); - } + // Validate collection of coordinates + if (!TryValidate(coordinates, ref exceptions)) { + throw new AggregateException(exceptions); + } - // Initializing local variables - int index = 0; - Memory buffer = new char[count * 12]; - int previousLatitude = 0; - int previousLongitude = 0; + // Initializing local variables + int index = 0; + Memory buffer = new char[count * 12]; + int previousLatitude = 0; + int previousLongitude = 0; - // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(Latitude); - int longitude = Round(Longitude); + // Looping over coordinates and building encoded result + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = Round(Latitude); + int longitude = Round(Longitude); - WriteNext(ref buffer, ref index, ref latitude, ref previousLatitude); - WriteNext(ref buffer, ref index, ref longitude, ref previousLongitude); - } + WriteNext(ref buffer, ref index, ref latitude, ref previousLatitude); + WriteNext(ref buffer, ref index, ref longitude, ref previousLongitude); + } - return buffer[..index].ToString(); + return buffer[..index].ToString(); - #region Local functions + #region Local functions - static bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { - foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } + static bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); } - - return exceptions.Count == 0; } - static int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - static void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { - int value = current - previous; - int shifted = value << 1; + return exceptions.Count == 0; + } - if (value < 0) { - shifted = ~shifted; - } + static int Round(double value) { + return (int)Math.Round(value * Constants.Precision); + } - int rem = shifted; + static void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { + int value = current - previous; + int shifted = value << 1; - while (rem >= Constants.ASCII.Space) { - buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - rem >>= Constants.ShiftLength; - index++; - } + if (value < 0) { + shifted = ~shifted; + } - buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); + int rem = shifted; + while (rem >= Constants.ASCII.Space) { + buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + rem >>= Constants.ShiftLength; index++; - - previous = current; } - #endregion - } - public static class CoordinateValidator { - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } + buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); - /// - /// Performs latitude validation - /// - /// Latitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } + index++; - /// - /// Performs longitude validation - /// - /// Longitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } + previous = current; } + #endregion + } - public class CoordinateValidationException(double latitude, double longitude) - : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { - public double Latitude { get; } + public static class CoordinateValidator { + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } - public double Longitude { get; } + /// + /// Performs latitude validation + /// + /// Latitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + /// + /// Performs longitude validation + /// + /// Longitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } } - private class V1 { - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates is null || !coordinates.Any()) { - throw new ArgumentException(nameof(coordinates)); - } + public class CoordinateValidationException(double latitude, double longitude) + : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { + public double Latitude { get; } - EnsureCoordinates(coordinates); + public double Longitude { get; } + } + } - int lastLatitude = 0; - int lastLongitude = 0; - var sb = new StringBuilder(); + private class V1 { + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates is null || !coordinates.Any()) { + throw new ArgumentException(nameof(coordinates)); + } - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = GetIntegerRepresentation(Latitude); - int longitude = GetIntegerRepresentation(Longitude); + EnsureCoordinates(coordinates); - sb.Append(GetEncodedCharacters(latitude - lastLatitude).ToArray()); - sb.Append(GetEncodedCharacters(longitude - lastLongitude).ToArray()); + int lastLatitude = 0; + int lastLongitude = 0; + var sb = new StringBuilder(); - lastLatitude = latitude; - lastLongitude = longitude; - } + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = GetIntegerRepresentation(Latitude); + int longitude = GetIntegerRepresentation(Longitude); + + sb.Append(GetEncodedCharacters(latitude - lastLatitude).ToArray()); + sb.Append(GetEncodedCharacters(longitude - lastLongitude).ToArray()); - return sb.ToString(); + lastLatitude = latitude; + lastLongitude = longitude; } - private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) { - var invalidCoordinates = coordinates - .Where(c => !CoordinateValidator.IsValid(c)); + return sb.ToString(); + } - if (invalidCoordinates.Any()) { - throw new AggregateException( - invalidCoordinates - .Select(c => - new ArgumentOutOfRangeException() - ) - ); - } + private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) { + var invalidCoordinates = coordinates + .Where(c => !CoordinateValidator.IsValid(c)); + + if (invalidCoordinates.Any()) { + throw new AggregateException( + invalidCoordinates + .Select(c => + new ArgumentOutOfRangeException() + ) + ); } + } - private static IEnumerable GetEncodedCharacters(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; + private static IEnumerable GetEncodedCharacters(int value) { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; - int rem = shifted; + int rem = shifted; - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } + while (rem >= Constants.ASCII.Space) { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - yield return (char)(rem + Constants.ASCII.QuestionMark); + rem >>= Constants.ShiftLength; } - private static int GetIntegerRepresentation(double value) { - return (int)Math.Round(value * Constants.Precision); - } + yield return (char)(rem + Constants.ASCII.QuestionMark); + } - public static class CoordinateValidator { - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } + private static int GetIntegerRepresentation(double value) { + return (int)Math.Round(value * Constants.Precision); + } - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } + public static class CoordinateValidator { + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } } + } - private class V2 { - private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, int.MaxValue); + private class V2 { + private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, int.MaxValue); - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates is null || !coordinates.Any()) { - throw new ArgumentException(nameof(coordinates)); - } + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates is null || !coordinates.Any()) { + throw new ArgumentException(nameof(coordinates)); + } - EnsureCoordinates(coordinates); + EnsureCoordinates(coordinates); - int previousLatitude = 0; - int previousLongitude = 0; + int previousLatitude = 0; + int previousLongitude = 0; - var sb = _pool.Get(); + var sb = _pool.Get(); - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = GetIntegerRepresentation(Latitude); - int longitude = GetIntegerRepresentation(Longitude); + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = GetIntegerRepresentation(Latitude); + int longitude = GetIntegerRepresentation(Longitude); - sb.Append(GetEncodedCharacters(latitude - previousLatitude).ToArray()); - sb.Append(GetEncodedCharacters(longitude - previousLongitude).ToArray()); + sb.Append(GetEncodedCharacters(latitude - previousLatitude).ToArray()); + sb.Append(GetEncodedCharacters(longitude - previousLongitude).ToArray()); - previousLatitude = latitude; - previousLongitude = longitude; - } + previousLatitude = latitude; + previousLongitude = longitude; + } - var result = sb.ToString(); + var result = sb.ToString(); - _pool.Return(sb); + _pool.Return(sb); + + return result; + } - return result; + private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) { + var invalidCoordinates = coordinates + .Where(c => !CoordinateValidator.IsValid(c)); + + if (invalidCoordinates.Any()) { + throw new AggregateException( + invalidCoordinates + .Select(c => + new ArgumentOutOfRangeException() + ) + ); } + } - private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) { - var invalidCoordinates = coordinates - .Where(c => !CoordinateValidator.IsValid(c)); + private static IEnumerable GetEncodedCharacters(int value) { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; - if (invalidCoordinates.Any()) { - throw new AggregateException( - invalidCoordinates - .Select(c => - new ArgumentOutOfRangeException() - ) - ); - } - } + int rem = shifted; - private static IEnumerable GetEncodedCharacters(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; + while (rem >= Constants.ASCII.Space) { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - int rem = shifted; + rem >>= Constants.ShiftLength; + } - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + yield return (char)(rem + Constants.ASCII.QuestionMark); + } - rem >>= Constants.ShiftLength; - } + private static int GetIntegerRepresentation(double value) { + return (int)Math.Round(value * Constants.Precision); + } - yield return (char)(rem + Constants.ASCII.QuestionMark); + public static class CoordinateValidator { + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); } - private static int GetIntegerRepresentation(double value) { - return (int)Math.Round(value * Constants.Precision); + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; } - public static class CoordinateValidator { - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } } + } - private class V3 { - /// - /// Method encodes coordinates to polyline encoded representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(); - } + private class V3 { + /// + /// Method encodes coordinates to polyline encoded representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null or empty enumerable + /// If one or more coordinate is out of range + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { + throw new ArgumentException(); + } - // Validate collection of coordinates - if (!TryValidate(coordinates, out var exceptions)) { - throw new AggregateException(exceptions); - } + // Validate collection of coordinates + if (!TryValidate(coordinates, out var exceptions)) { + throw new AggregateException(exceptions); + } - // Initializing local variables - int previousLatitude = 0; - int previousLongitude = 0; - var sb = new StringBuilder(coordinates.Count() * 4); + // Initializing local variables + int previousLatitude = 0; + int previousLongitude = 0; + var sb = new StringBuilder(coordinates.Count() * 4); - // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(Latitude); - int longitude = Round(Longitude); + // Looping over coordinates and building encoded result + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = Round(Latitude); + int longitude = Round(Longitude); - sb.Append(GetSequence(latitude - previousLatitude).ToArray()); - sb.Append(GetSequence(longitude - previousLongitude).ToArray()); + sb.Append(GetSequence(latitude - previousLatitude).ToArray()); + sb.Append(GetSequence(longitude - previousLongitude).ToArray()); - previousLatitude = latitude; - previousLongitude = longitude; - } + previousLatitude = latitude; + previousLongitude = longitude; + } - return sb.ToString(); + return sb.ToString(); - #region Local functions + #region Local functions - bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) { - exceptions = new List(collection.Count()); + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) { + exceptions = new List(collection.Count()); - foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); } - - return !exceptions.GetEnumerator().MoveNext(); } - int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } + return !exceptions.GetEnumerator().MoveNext(); + } - IEnumerable GetSequence(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; + int Round(double value) { + return (int)Math.Round(value * Constants.Precision); + } - int rem = shifted; + IEnumerable GetSequence(int value) { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + int rem = shifted; - rem >>= Constants.ShiftLength; - } + while (rem >= Constants.ASCII.Space) { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - yield return (char)(rem + Constants.ASCII.QuestionMark); + rem >>= Constants.ShiftLength; } - #endregion + yield return (char)(rem + Constants.ASCII.QuestionMark); } - public static class CoordinateValidator { - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - /// - /// Performs latitude validation - /// - /// Latitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } + #endregion + } - /// - /// Performs longitude validation - /// - /// Longitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } + public static class CoordinateValidator { + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); } - public class CoordinateValidationException(double latitude, double longitude) - : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { - public double Latitude { get; } + /// + /// Performs latitude validation + /// + /// Latitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } - public double Longitude { get; } + /// + /// Performs longitude validation + /// + /// Longitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } } - private class V4 { - private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); + public class CoordinateValidationException(double latitude, double longitude) + : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { + public double Latitude { get; } - /// - /// Method encodes coordinates to polyline encoded representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(); - } + public double Longitude { get; } + } + } - int count = coordinates.Count(); - ICollection exceptions = new List(count); + private class V4 { + private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); + + /// + /// Method encodes coordinates to polyline encoded representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null or empty enumerable + /// If one or more coordinate is out of range + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { + throw new ArgumentException(); + } - // Validate collection of coordinates - if (!TryValidate(coordinates, ref exceptions)) { - throw new AggregateException(exceptions); - } + int count = coordinates.Count(); + ICollection exceptions = new List(count); - // Initializing local variables - int previousLatitude = 0; - int previousLongitude = 0; - var sb = _pool.Get(); + // Validate collection of coordinates + if (!TryValidate(coordinates, ref exceptions)) { + throw new AggregateException(exceptions); + } - // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(Latitude); - int longitude = Round(Longitude); + // Initializing local variables + int previousLatitude = 0; + int previousLongitude = 0; + var sb = _pool.Get(); - sb.Append(GetSequence(latitude - previousLatitude).ToArray()); - sb.Append(GetSequence(longitude - previousLongitude).ToArray()); + // Looping over coordinates and building encoded result + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = Round(Latitude); + int longitude = Round(Longitude); - previousLatitude = latitude; - previousLongitude = longitude; - } + sb.Append(GetSequence(latitude - previousLatitude).ToArray()); + sb.Append(GetSequence(longitude - previousLongitude).ToArray()); - return sb.ToString(); + previousLatitude = latitude; + previousLongitude = longitude; + } - #region Local functions + return sb.ToString(); - bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { - foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } - } + #region Local functions - return exceptions.Count == 0; + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); + } } - int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } + return exceptions.Count == 0; + } - IEnumerable GetSequence(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; + int Round(double value) { + return (int)Math.Round(value * Constants.Precision); + } - int rem = shifted; + IEnumerable GetSequence(int value) { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + int rem = shifted; - rem >>= Constants.ShiftLength; - } + while (rem >= Constants.ASCII.Space) { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - yield return (char)(rem + Constants.ASCII.QuestionMark); + rem >>= Constants.ShiftLength; } - #endregion + yield return (char)(rem + Constants.ASCII.QuestionMark); } - public static class CoordinateValidator { - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - /// - /// Performs latitude validation - /// - /// Latitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } + #endregion + } - /// - /// Performs longitude validation - /// - /// Longitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } + public static class CoordinateValidator { + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); } - public class CoordinateValidationException(double latitude, double longitude) - : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { - public double Latitude { get; } + /// + /// Performs latitude validation + /// + /// Latitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } - public double Longitude { get; } + /// + /// Performs longitude validation + /// + /// Longitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } } - private class V5 { - private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); + public class CoordinateValidationException(double latitude, double longitude) + : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { + public double Latitude { get; } - /// - /// Method encodes coordinates to polyline encoded representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(); - } + public double Longitude { get; } + } + } + + private class V5 { + private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); + + /// + /// Method encodes coordinates to polyline encoded representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null or empty enumerable + /// If one or more coordinate is out of range + public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { + throw new ArgumentException(); + } - int count = coordinates.Count(); - ICollection exceptions = new List(count); + int count = coordinates.Count(); + ICollection exceptions = new List(count); - // Validate collection of coordinates - if (!TryValidate(coordinates, ref exceptions)) { - throw new AggregateException(exceptions); - } + // Validate collection of coordinates + if (!TryValidate(coordinates, ref exceptions)) { + throw new AggregateException(exceptions); + } - // Initializing local variables - int previousLatitude = 0; - int previousLongitude = 0; - var sb = _pool.Get(); + // Initializing local variables + int previousLatitude = 0; + int previousLongitude = 0; + var sb = _pool.Get(); - // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(Latitude); - int longitude = Round(Longitude); + // Looping over coordinates and building encoded result + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = Round(Latitude); + int longitude = Round(Longitude); - sb.Append(GetSequence(latitude - previousLatitude).ToArray()); - sb.Append(GetSequence(longitude - previousLongitude).ToArray()); + sb.Append(GetSequence(latitude - previousLatitude).ToArray()); + sb.Append(GetSequence(longitude - previousLongitude).ToArray()); - previousLatitude = latitude; - previousLongitude = longitude; - } + previousLatitude = latitude; + previousLongitude = longitude; + } - return sb.ToString(); + return sb.ToString(); - #region Local functions + #region Local functions - bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { - foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); } - - return exceptions.Count == 0; } - int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } + return exceptions.Count == 0; + } - IEnumerable GetSequence(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; + int Round(double value) { + return (int)Math.Round(value * Constants.Precision); + } - int rem = shifted; + IEnumerable GetSequence(int value) { + int shifted = value << 1; + if (value < 0) + shifted = ~shifted; - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + int rem = shifted; - rem >>= Constants.ShiftLength; - } + while (rem >= Constants.ASCII.Space) { + yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - yield return (char)(rem + Constants.ASCII.QuestionMark); + rem >>= Constants.ShiftLength; } - #endregion + yield return (char)(rem + Constants.ASCII.QuestionMark); } - public static class CoordinateValidator { - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - /// - /// Performs latitude validation - /// - /// Latitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } + #endregion + } - /// - /// Performs longitude validation - /// - /// Longitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } + public static class CoordinateValidator { + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); } - public class CoordinateValidationException(double latitude, double longitude) - : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { - public double Latitude { get; } - - public double Longitude { get; } + /// + /// Performs latitude validation + /// + /// Latitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; } - } - - private class V6 { - public static V6 Default = new(); /// - /// Method encodes coordinates to polyline encoded representation + /// Performs longitude validation /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(); - } - - int count = coordinates.Count(); - ICollection exceptions = new List(count); + /// Longitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + } - // Validate collection of coordinates - if (!TryValidate(coordinates, ref exceptions)) { - throw new AggregateException(exceptions); - } + public class CoordinateValidationException(double latitude, double longitude) + : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { + public double Latitude { get; } - // Initializing local variables - int index = 0; - Memory buffer = new char[count * 12]; - int previousLatitude = 0; - int previousLongitude = 0; + public double Longitude { get; } + } + } - // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(Latitude); - int longitude = Round(Longitude); + private class V6 { + public static V6 Default = new(); + + /// + /// Method encodes coordinates to polyline encoded representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null or empty enumerable + /// If one or more coordinate is out of range + public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { + throw new ArgumentException(); + } - WriteNext(ref buffer, ref index, ref latitude, ref previousLatitude); - WriteNext(ref buffer, ref index, ref longitude, ref previousLongitude); - } + int count = coordinates.Count(); + ICollection exceptions = new List(count); - return buffer[..index].ToString(); + // Validate collection of coordinates + if (!TryValidate(coordinates, ref exceptions)) { + throw new AggregateException(exceptions); } - bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { - foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } - } + // Initializing local variables + int index = 0; + Memory buffer = new char[count * 12]; + int previousLatitude = 0; + int previousLongitude = 0; - return exceptions.Count == 0; - } + // Looping over coordinates and building encoded result + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = Round(Latitude); + int longitude = Round(Longitude); - int Round(double value) { - return (int)Math.Round(value * Constants.Precision); + WriteNext(ref buffer, ref index, ref latitude, ref previousLatitude); + WriteNext(ref buffer, ref index, ref longitude, ref previousLongitude); } - void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { - int value = current - previous; - int shifted = value << 1; + return buffer[..index].ToString(); + } - if (value < 0) { - shifted = ~shifted; + bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); } + } - int rem = shifted; + return exceptions.Count == 0; + } - while (rem >= Constants.ASCII.Space) { - buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - rem >>= Constants.ShiftLength; - index++; - } + int Round(double value) { + return (int)Math.Round(value * Constants.Precision); + } - buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); + void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { + int value = current - previous; + int shifted = value << 1; - index++; + if (value < 0) { + shifted = ~shifted; + } - previous = current; + int rem = shifted; + + while (rem >= Constants.ASCII.Space) { + buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + rem >>= Constants.ShiftLength; + index++; } - public static class CoordinateValidator { - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } + buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); - /// - /// Performs latitude validation - /// - /// Latitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } + index++; - /// - /// Performs longitude validation - /// - /// Longitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } + previous = current; + } + + public static class CoordinateValidator { + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); } - public class CoordinateValidationException(double latitude, double longitude) - : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { - public double Latitude { get; } + /// + /// Performs latitude validation + /// + /// Latitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } - public double Longitude { get; } + /// + /// Performs longitude validation + /// + /// Longitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } } + + public class CoordinateValidationException(double latitude, double longitude) + : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { + public double Latitude { get; } + + public double Longitude { get; } + } } } diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs index e9f7ba3a..5b4f6f80 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs @@ -1,17 +1,17 @@ // -// Copyright (c) Petr Å rámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Implementation.Benchmarks { - using BenchmarkDotNet.Running; +namespace PolylineAlgorithm.Implementation.Benchmarks; - internal class Program { - static void Main(string[] _) { - BenchmarkRunner - .Run(); - BenchmarkRunner - .Run(); - } +using BenchmarkDotNet.Running; + +internal class Program { + static void Main(string[] _) { + BenchmarkRunner + .Run(); + BenchmarkRunner + .Run(); } } diff --git a/src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs b/src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs new file mode 100644 index 00000000..866bb63b --- /dev/null +++ b/src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs @@ -0,0 +1,31 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.DependencyInjection.Autofac; + +using global::Autofac; + +public static class ContainerBuilderExtensions { + /// + /// Registers singleton instances of + /// , + /// and + /// into . + /// + /// Instance of to register polyline services into. + public static void RegisterPolylineAlgorithm(this ContainerBuilder builder) { + builder.RegisterType() + .As() + .SingleInstance(); + + builder.RegisterType() + .As() + .SingleInstance(); + + builder.RegisterType() + .As() + .SingleInstance(); + } +} diff --git a/src/PolylineAlgorithm.DependencyInjection.Autofac/PolylineAlgorithm.DependencyInjection.Autofac.csproj b/src/PolylineAlgorithm.DependencyInjection.Autofac/PolylineAlgorithm.DependencyInjection.Autofac.csproj new file mode 100644 index 00000000..f9cf1337 --- /dev/null +++ b/src/PolylineAlgorithm.DependencyInjection.Autofac/PolylineAlgorithm.DependencyInjection.Autofac.csproj @@ -0,0 +1,27 @@ + + + + netstandard2.1 + 13.0 + enable + enable + true + + + + All + latest + true + true + true + + + + + + + + + + + diff --git a/src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj b/src/PolylineAlgorithm.DependencyInjection.Microsoft/PolylineAlgorithm.DependencyInjection.Microsoft.csproj similarity index 100% rename from src/PolylineAlgorithm.DependencyInjection/PolylineAlgorithm.DependencyInjection.csproj rename to src/PolylineAlgorithm.DependencyInjection.Microsoft/PolylineAlgorithm.DependencyInjection.Microsoft.csproj diff --git a/src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs b/src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs new file mode 100644 index 00000000..cc371bb4 --- /dev/null +++ b/src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs @@ -0,0 +1,25 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.DependencyInjection.Microsoft; + +using global::Microsoft.Extensions.DependencyInjection; + +public static class ServiceCollectionExtensions { + /// + /// Registers singleton instances of + /// , + /// and + /// to . + /// + /// Instance of + /// Instance of + public static IServiceCollection AddPolylineAlgorithm(this IServiceCollection services) { + return services + .AddSingleton() + .AddSingleton() + .AddSingleton(); + } +} diff --git a/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs b/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs deleted file mode 100644 index adb9269c..00000000 --- a/src/PolylineAlgorithm.DependencyInjection/ServiceCollectionExtensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.DependencyInjection { - using Microsoft.Extensions.DependencyInjection; - - public static class ServiceCollectionExtensions { - /// - /// Registers singleton instance of to dependency container. - /// - /// Instance of - /// nstance of - public static IServiceCollection AddPolylineAlgorithm(this IServiceCollection services) { - return services - .AddSingleton() - .AddSingleton() - .AddSingleton(); - } - } -} diff --git a/src/PolylineAlgorithm/CoordinateValidationException.cs b/src/PolylineAlgorithm/CoordinateValidationException.cs index 0c348f09..d398899b 100644 --- a/src/PolylineAlgorithm/CoordinateValidationException.cs +++ b/src/PolylineAlgorithm/CoordinateValidationException.cs @@ -1,12 +1,37 @@ -namespace PolylineAlgorithm { - using System; +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// - public sealed class CoordinateValidationException : Exception { - public CoordinateValidationException(double latitude, double longitude) - : base(string.Format(ExceptionMessageResource.CoordinateValidationExceptionCoordinateIsOutOfRangeErrorMessageFormat, latitude, longitude)) { } +namespace PolylineAlgorithm; - public double Latitude { get; } +using System; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; - public double Longitude { get; } - } +/// +/// The exception that is thrown when coordinate is not valid. +/// +/// An invalid coordinate that caused the exception. +[DebuggerDisplay($"{{{nameof(GetFormattedMessage)}(),nq}}")] +[SuppressMessage("Design", "CA1032:Implement standard exception constructors", Justification = "There is no reason to have standard constructors.")] +public sealed class CoordinateValidationException((double Latitude, double Longitude) coordinate) + : Exception(GetFormattedMessage(coordinate)) { + + /// + /// An invalid coordinate that caused the exception. + /// + public (double Latitude, double Longitude) Coordinate { get; } + + /// + /// Returns a formatted exception message. + /// + /// An invalid coordinate that caused the exception. + /// A formatted exception message. + private static string GetFormattedMessage((double Latitude, double Longitude) coordinate) + => string.Format( + ExceptionMessageResource.CoordinateValidationExceptionCoordinateIsOutOfRangeErrorMessageFormat, + coordinate.Latitude, + coordinate.Longitude + ); } diff --git a/src/PolylineAlgorithm/CoordinateValidator.cs b/src/PolylineAlgorithm/CoordinateValidator.cs index f222bc89..b9d125de 100644 --- a/src/PolylineAlgorithm/CoordinateValidator.cs +++ b/src/PolylineAlgorithm/CoordinateValidator.cs @@ -1,25 +1,33 @@ -using PolylineAlgorithm.Internal; +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; + +using PolylineAlgorithm.Internal; + +/// +public sealed class CoordinateValidator : ICoordinateValidator { + public bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(ref coordinate.Latitude) && IsValidLongitude(ref coordinate.Longitude); + } -namespace PolylineAlgorithm { /// - /// Performs coordinate validation + /// Determines whether the value of a latitude is valid. /// - public sealed class CoordinateValidator : ICoordinateValidator { - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(ref coordinate.Latitude) && IsValidLongitude(ref coordinate.Longitude); - } - - private static bool IsValidLatitude(ref readonly double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } + /// The latitude to be validated. + /// if the parameter is a valid; otherwise, . + private static bool IsValidLatitude(ref readonly double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } - private static bool IsValidLongitude(ref readonly double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } + /// + /// Determines whether the value of a latitude is valid. + /// + /// The longitude to be validated. + /// if the parameter is a valid; otherwise, . + private static bool IsValidLongitude(ref readonly double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; } } diff --git a/src/PolylineAlgorithm/ICoordinateValidator.cs b/src/PolylineAlgorithm/ICoordinateValidator.cs index 023023f8..9d95ce25 100644 --- a/src/PolylineAlgorithm/ICoordinateValidator.cs +++ b/src/PolylineAlgorithm/ICoordinateValidator.cs @@ -1,5 +1,18 @@ -namespace PolylineAlgorithm; +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// +namespace PolylineAlgorithm; + +/// +/// Provides validation of a coordinate value. +/// public interface ICoordinateValidator { + /// + /// Determines whether the value of a coordinate is valid. + /// + /// The coordinate value to be validated. + /// if the parameter is a valid; otherwise, . bool IsValid((double Latitude, double Longitude) coordinate); } \ No newline at end of file diff --git a/src/PolylineAlgorithm/IPolylineDecoder.cs b/src/PolylineAlgorithm/IPolylineDecoder.cs index 7f8fcb67..17ebaa75 100644 --- a/src/PolylineAlgorithm/IPolylineDecoder.cs +++ b/src/PolylineAlgorithm/IPolylineDecoder.cs @@ -1,7 +1,20 @@ -namespace PolylineAlgorithm; +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; using System.Collections.Generic; +/// +/// Converts an encoded polyline string into a set of latitude and longitude coordinates. +/// public interface IPolylineDecoder { + /// + /// Decodes an encoded polyline string into a set of value tuples representing latitude and longitude coordinates. + /// + /// An encoded polyline string to decode. + /// A set of value tuples representing latitude and longitude coordinates. IEnumerable<(double Latitude, double Longitude)> Decode(string polyline); } \ No newline at end of file diff --git a/src/PolylineAlgorithm/IPolylineEncoder.cs b/src/PolylineAlgorithm/IPolylineEncoder.cs index 9a5b6d3d..541f514d 100644 --- a/src/PolylineAlgorithm/IPolylineEncoder.cs +++ b/src/PolylineAlgorithm/IPolylineEncoder.cs @@ -1,5 +1,5 @@ // -// Copyright (c) Petr Å rámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // @@ -7,6 +7,14 @@ namespace PolylineAlgorithm; using System.Collections.Generic; +/// +/// Converts a set of latitude and longitude coordinates into an encoded polyline string. +/// public interface IPolylineEncoder { + /// + /// Encodes a set of value tuples representing latitude and longitude coordinates into an encoded polyline string. + /// + /// A set of value tuples representing latitude and longitude coordinates. + /// An encoded polyline string representing a set of latitude and longitude coordinates. string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates); } \ No newline at end of file diff --git a/src/PolylineAlgorithm/Internal/Constants.cs b/src/PolylineAlgorithm/Internal/Constants.cs index 84727ea3..f8babb76 100644 --- a/src/PolylineAlgorithm/Internal/Constants.cs +++ b/src/PolylineAlgorithm/Internal/Constants.cs @@ -1,5 +1,5 @@ // -// Copyright (c) Petr Å rámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // diff --git a/src/PolylineAlgorithm/PolylineDecoder.cs b/src/PolylineAlgorithm/PolylineDecoder.cs index dddee225..4f8b2ddc 100644 --- a/src/PolylineAlgorithm/PolylineDecoder.cs +++ b/src/PolylineAlgorithm/PolylineDecoder.cs @@ -1,17 +1,20 @@ -namespace PolylineAlgorithm; +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; using PolylineAlgorithm.Internal; +/// +/// A coordinate validator. public sealed class PolylineDecoder(ICoordinateValidator validator) : IPolylineDecoder { public ICoordinateValidator Validator { get; } = validator ?? throw new ArgumentNullException(nameof(validator)); - /// - /// Decodes polyline representation. - /// - /// Encoded polyline string to decode - /// Returns coordinates - /// If polyline argument is null -or- empty char array. - /// If polyline representation is not in correct format. + /// + /// Thrown when argument is null -or- empty. + /// Thrown when is not in correct format. public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { // Checking null and at least one character if (polyline == null || polyline.Length == 0) { @@ -25,19 +28,19 @@ public sealed class PolylineDecoder(ICoordinateValidator validator) : IPolylineD // Looping through encoded polyline char array while (index < polyline.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref latitude)) { + // Attempting to calculate next latitude value. If failed exception is thrown. + if (!TryDecodeNext(polyline, ref index, ref latitude)) { throw new InvalidOperationException(string.Empty); } - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref longitude)) { + // Attempting to calculate next longitude value. If failed exception is thrown. + if (!TryDecodeNext(polyline, ref index, ref longitude)) { throw new InvalidOperationException(string.Empty); } var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - // Validating decoded coordinate. If not valid exception is thrown + // Validating decoded coordinate. If not valid exception is thrown. if (!Validator.IsValid(coordinate)) { throw new InvalidOperationException(string.Empty); } @@ -46,7 +49,14 @@ public sealed class PolylineDecoder(ICoordinateValidator validator) : IPolylineD } } - private static bool TryCalculateNext(string polyline, ref int index, ref int value) { + /// + /// + /// + /// + /// + /// + /// + private static bool TryDecodeNext(string polyline, ref int index, ref int value) { // Initialize local variables int chunk; int sum = 0; diff --git a/src/PolylineAlgorithm/PolylineEncoder.cs b/src/PolylineAlgorithm/PolylineEncoder.cs index a8992e96..f4af4ed9 100644 --- a/src/PolylineAlgorithm/PolylineEncoder.cs +++ b/src/PolylineAlgorithm/PolylineEncoder.cs @@ -1,103 +1,102 @@ // -// Copyright (c) Petr Å rámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // +namespace PolylineAlgorithm; + using PolylineAlgorithm.Internal; +using System; +using System.Collections.Generic; +using System.Linq; -namespace PolylineAlgorithm { - using System; - using System.Collections.Generic; - using System.Linq; +/// +/// Performs polyline algorithm decoding and encoding +/// +public sealed class PolylineEncoder(ICoordinateValidator validator) : IPolylineEncoder { + public ICoordinateValidator Validator { get; } = validator ?? throw new ArgumentNullException(nameof(validator)); /// - /// Performs polyline algorithm decoding and encoding + /// Encodes coordinates to polyline representation /// - public sealed class PolylineEncoder(ICoordinateValidator validator) : IPolylineEncoder { - public ICoordinateValidator Validator { get; } = validator ?? throw new ArgumentNullException(nameof(validator)); - - /// - /// Encodes coordinates to polyline representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null - /// If coordinates parameter is empty - /// If one or more coordinate is out of valid range - public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates is null) { - throw new ArgumentNullException(nameof(coordinates)); - } - - if (!coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeEmptyEnumerable, nameof(coordinates)); - } - - int count = coordinates.Count(); - ICollection exceptions = new List(count); + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null + /// If coordinates parameter is empty + /// If one or more coordinate is out of valid range + public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates is null) { + throw new ArgumentNullException(nameof(coordinates)); + } - // Validate collection of coordinates - if (!TryValidate(coordinates, ref exceptions)) { - throw new AggregateException(ExceptionMessageResource.AggregateExceptionCoordinatesAreInvalidErrorMessage, exceptions); - } + if (!coordinates.GetEnumerator().MoveNext()) { + throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeEmptyEnumerable, nameof(coordinates)); + } - // Initializing local variables - int index = 0; - Memory buffer = new char[GetSafeBufferSize(count)]; - int previousLatitude = 0; - int previousLongitude = 0; + int count = coordinates.Count(); + ICollection exceptions = new List(count); - // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(Latitude); - int longitude = Round(Longitude); + // Validate collection of coordinates + if (!TryValidate(coordinates, ref exceptions)) { + throw new AggregateException(ExceptionMessageResource.AggregateExceptionCoordinatesAreInvalidErrorMessage, exceptions); + } - WriteNext(ref buffer, ref index, ref latitude, ref previousLatitude); - WriteNext(ref buffer, ref index, ref longitude, ref previousLongitude); - } + // Initializing local variables + int index = 0; + Memory buffer = new char[GetSafeBufferSize(count)]; + int previousLatitude = 0; + int previousLongitude = 0; - return buffer[..index].ToString(); + // Looping over coordinates and building encoded result + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = Round(Latitude); + int longitude = Round(Longitude); - // Each coordinate consist of two values, each one is 4 or 5 chars long - // We use constant 12 = [2 * 6] to create safe buffer size - static int GetSafeBufferSize(int count) => count * 12; + WriteNext(ref buffer, ref index, ref latitude, ref previousLatitude); + WriteNext(ref buffer, ref index, ref longitude, ref previousLongitude); } - private bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { - foreach (var item in collection) { - if (!Validator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } - } + return buffer[..index].ToString(); - return exceptions.Count == 0; - } + // Each coordinate consist of two values, each one is 4 or 5 chars long + // We use 12 = [2 * 6] to create safe buffer size + static int GetSafeBufferSize(int count) => count * 12; + } - private static int Round(double value) { - return (int)Math.Round(value * Constants.Precision); + private bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { + foreach (var item in collection) { + if (!Validator.IsValid(item)) { + exceptions.Add(new CoordinateValidationException(item)); + } } - private static void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { - int value = current - previous; - int shifted = value << 1; + return exceptions.Count == 0; + } - if (value < 0) { - shifted = ~shifted; - } + private static int Round(double value) { + return (int)Math.Round(value * Constants.Precision); + } - int rem = shifted; + private static void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { + int value = current - previous; + int shifted = value << 1; - while (rem >= Constants.ASCII.Space) { - buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - rem >>= Constants.ShiftLength; - index++; - } + if (value < 0) { + shifted = ~shifted; + } - buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); + int rem = shifted; + while (rem >= Constants.ASCII.Space) { + buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + rem >>= Constants.ShiftLength; index++; - - previous = current; } + + buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); + + index++; + + previous = current; } } diff --git a/tests/Encoding/PolylineEncodingBaseTest.cs b/tests/Encoding/PolylineEncodingBaseTest.cs deleted file mode 100644 index e202c83e..00000000 --- a/tests/Encoding/PolylineEncodingBaseTest.cs +++ /dev/null @@ -1,192 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Tests.Encoding -{ - using PolylineAlgorithm.Encoding; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using System; - using System.Collections.Generic; - using System.Linq; - - /// - /// Defines the - /// - [TestClass] - [TestCategory(nameof(PolylineEncodingBase<(double latitude, double longitude)>))] - public class PolylineEncodingBaseTest : PolylineEncodingBase<(double latitude, double longitude)> - { - /// - /// The Decode_NullInput - /// - [TestMethod] - public void Decode_NullInput_ThrowsException() - { - // Arrange - var nullPolylineString = (string)null; - - // Act - void DecodeNullPolylineString() - { - this.Decode(nullPolylineString).ToArray(); - } - - // Assert - Assert.ThrowsException(() => DecodeNullPolylineString()); - } - - /// - /// The Decode_EmptyInput - /// - [TestMethod] - public void Decode_EmptyInput_ThrowsException() - { - // Arrange - var emptyPolylineString = Defaults.Polyline.Empty; - - // Act - void DecodeEmptyPolylineString() - { - this.Decode(emptyPolylineString).ToArray(); - } - - // Assert - Assert.ThrowsException(() => DecodeEmptyPolylineString()); - } - - /// - /// The Decode_InvalidInput - /// - [TestMethod] - public void Decode_InvalidInput_ThrowsException() - { - // Arrange - var invalidPolylineString = Defaults.Polyline.Invalid; - - // Act - void DecodeInvalidPolylineString() - { - this.Decode(Defaults.Polyline.Invalid).ToArray(); - } - - // Assert - Assert.ThrowsException(() => DecodeInvalidPolylineString()); - } - - /// - /// The Decode_ValidInput - /// - [TestMethod] - public void Decode_ValidInput_AreEquivalent() - { - // Arrange - var validPolylineString = Defaults.Polyline.Valid; - - // Act - var result = this.Decode(validPolylineString).ToArray(); - - // Assert - CollectionAssert.AreEquivalent(Defaults.Coordinate.Valid.ToList(), result.ToList()); - } - - /// - /// The Encode_NullInput - /// - [TestMethod] - public void Encode_NullInput_ThrowsException() - { - // Arrange - var nullCoordinates = (IEnumerable<(double, double)>)null; - - // Act - void EncodeNullCoordinateCollection() - { - this.Encode(nullCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeNullCoordinateCollection()); - } - - /// - /// The Encode_EmptyInput - /// - [TestMethod] - public void Encode_EmptyInput_ThrowsException() - { - // Arrange - var emptyCoordinates = Defaults.Coordinate.Empty; - - // Act - void EncodeEmptyCoordinateCollection() - { - this.Encode(emptyCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeEmptyCoordinateCollection()); - } - - /// - /// The Encode_InvalidInput - /// - [TestMethod] - public void Encode_InvalidInput_ThrowsException() - { - // Arrange - var invalidCoordinates = Defaults.Coordinate.Invalid; - - // Act - void EncodeInvalidCoordinateCollection() - { - this.Encode(invalidCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeInvalidCoordinateCollection()); - } - - /// - /// The Encode_ValidInput - /// - [TestMethod] - public void Encode_ValidInput_AreEqual() - { - // Arrange - var validCoordinateCollection = Defaults.Coordinate.Valid; - - // Act - var result = this.Encode(validCoordinateCollection); - - // Assert - Assert.AreEqual(Defaults.Polyline.Valid, result); - } - - #region Overriden methods - - /// - /// The CreateResult - /// - /// The - /// The - /// The - protected override (double latitude, double longitude) CreateResult(double latitude, double longitude) - { - return (latitude, longitude); - } - - /// - /// The GetCoordinate - /// - /// The - /// The - protected override (double Latitude, double Longitude) GetCoordinate((double latitude, double longitude) source) - { - return source; - } - - #endregion - } -} diff --git a/tests/Encoding/PolylineEncodingTest.cs b/tests/Encoding/PolylineEncodingTest.cs deleted file mode 100644 index ddcf5e00..00000000 --- a/tests/Encoding/PolylineEncodingTest.cs +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Tests.Encoding -{ - using PolylineAlgorithm.Encoding; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using System.Linq; - - /// - /// Defines the - /// - [TestClass] - [TestCategory(nameof(PolylineEncoding))] - public class PolylineEncodingTest : PolylineEncoding - { - /// - /// The CreateResult_AreEqual - /// - [TestMethod] - public void CreateResult_AreEqual() - { - // Arrange - var validCoordinate = Defaults.Coordinate.Valid.First(); - - // Act - var result = this.CreateResult(validCoordinate.Latitude, validCoordinate.Longitude); - - // Assert - Assert.AreEqual(validCoordinate, result); - } - - /// - /// The GetCoordinate_AreEqual - /// - [TestMethod] - public void GetCoordinate_AreEqual() - { - // Arrange - var validCoordinate = Defaults.Coordinate.Valid.First(); - - // Act - var result = this.GetCoordinate(validCoordinate); - - // Assert - Assert.AreEqual(validCoordinate, result); - } - } -} diff --git a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs new file mode 100644 index 00000000..bfd87e10 --- /dev/null +++ b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs @@ -0,0 +1,65 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.DependencyInjection.Autofac.Tests; + +using PolylineAlgorithm.DependencyInjection.Autofac; + +[TestClass] +public class ContainerBuilderExtensionsTests { +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. + private static IContainer Container { get; set; } +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. + + [ClassInitialize] + public static void ClassInitialize(TestContext context) { + var builder = new ContainerBuilder(); + + builder + .RegisterPolylineAlgorithm(); + + Container = builder + .Build(); + } + + [TestMethod] + public void Resolve_CoordinateValidator_Test() { + // Arrange + var container = Container; + + // Act + var validator = container + .Resolve(); + + // Assert + Assert.IsInstanceOfType(validator); + } + + [TestMethod] + public void Resolve_PolylineEncoder_Test() { + // Arrange + var container = Container; + + // Act + var encoder = container + .Resolve(); + + // Assert + Assert.IsInstanceOfType(encoder); + } + + [TestMethod] + public void Resolve_PolylineDecoder_Test() { + // Arrange + var container = Container; + + // Act + var decoder = container + .Resolve(); + + // Assert + Assert.IsInstanceOfType(decoder); + } +} \ No newline at end of file diff --git a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalSuppressions.cs b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalSuppressions.cs new file mode 100644 index 00000000..0b97243b --- /dev/null +++ b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Applies only to production code. Test assemblies are not production code.")] diff --git a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalUsings.cs b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalUsings.cs new file mode 100644 index 00000000..3464acd3 --- /dev/null +++ b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalUsings.cs @@ -0,0 +1,7 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +global using Autofac; +global using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests.csproj b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests.csproj new file mode 100644 index 00000000..4b9269c4 --- /dev/null +++ b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests.csproj @@ -0,0 +1,42 @@ + + + + net9.0 + 13.0 + enable + enable + true + + + + false + true + + + + All + latest + true + false + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/Properties/AssemblyInfo.cs b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/Properties/AssemblyInfo.cs similarity index 76% rename from tests/PolylineAlgorithm.DependencyInjection.Tests/Properties/AssemblyInfo.cs rename to tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/Properties/AssemblyInfo.cs index e517ce6d..aae125e3 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/Properties/AssemblyInfo.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/Properties/AssemblyInfo.cs @@ -1,5 +1,5 @@ // -// Copyright (c) Petr Å rámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // diff --git a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalSuppressions.cs b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalSuppressions.cs new file mode 100644 index 00000000..0b97243b --- /dev/null +++ b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Applies only to production code. Test assemblies are not production code.")] diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalUsings.cs similarity index 81% rename from tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs rename to tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalUsings.cs index 1b7250b9..1a2cced1 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalUsings.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalUsings.cs @@ -1,5 +1,5 @@ // -// Copyright (c) Petr Šrámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests.csproj similarity index 89% rename from tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj rename to tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests.csproj index f937732f..3984b45d 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/PolylineAlgorithm.DependencyInjection.Tests.csproj +++ b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests.csproj @@ -21,7 +21,7 @@ - + all @@ -36,7 +36,7 @@ - + diff --git a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/Properties/AssemblyInfo.cs b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..aae125e3 --- /dev/null +++ b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] \ No newline at end of file diff --git a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs new file mode 100644 index 00000000..fc11ae84 --- /dev/null +++ b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs @@ -0,0 +1,55 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.DependencyInjection.Tests; + +using PolylineAlgorithm.DependencyInjection.Microsoft; + +[TestClass] +public class ServiceCollectionExtensionsTests { + private static IServiceCollection Services { get; } = new ServiceCollection().AddPolylineAlgorithm(); + + [TestMethod] + public void Resolve_CoordinateValidator_Test() { + // Arrange + var provider = Services + .BuildServiceProvider(); + + // Act + var validator = provider + .GetRequiredService(); + + // Assert + Assert.IsInstanceOfType(validator); + } + + [TestMethod] + public void Resolve_PolylineEncoder_Test() { + // Arrange + var provider = Services + .BuildServiceProvider(); + + // Act + var encoder = provider + .GetRequiredService(); + + // Assert + Assert.IsInstanceOfType(encoder); + } + + [TestMethod] + public void Resolve_PolylineDecoder_Test() { + // Arrange + var provider = Services + .BuildServiceProvider(); + + // Act + var decoder = provider + .GetRequiredService(); + + // Assert + Assert.IsInstanceOfType(decoder); + } +} \ No newline at end of file diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalSuppressions.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalSuppressions.cs deleted file mode 100644 index dfd5bb25..00000000 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/GlobalSuppressions.cs +++ /dev/null @@ -1,8 +0,0 @@ -// This file is used by Code Analysis to maintain SuppressMessage -// attributes that are applied to this project. -// Project-level suppressions either have no target or are given -// a specific target and scoped to a namespace, type, member, etc. - -using System.Diagnostics.CodeAnalysis; - -[assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Applies only to production code. Test assemblies are not production code.")] diff --git a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs deleted file mode 100644 index 294a53ec..00000000 --- a/tests/PolylineAlgorithm.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright (c) Petr Šrámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.DependencyInjection.Tests { - - [TestClass] - public class ServiceCollectionExtensionsTests { - private static IServiceCollection Services { get; } = new ServiceCollection().AddPolylineAlgorithm(); - - [TestMethod] - public void Add_CoordinateValidator_Test() { - // Arrange - var provider = Services - .BuildServiceProvider(); - - // Act - var encoder = provider - .GetRequiredService(); - - // Assert - Assert.IsInstanceOfType(encoder); - } - - [TestMethod] - public void Add_PolylineEncoder_Test() { - // Arrange - var provider = Services - .BuildServiceProvider(); - - // Act - var encoder = provider - .GetRequiredService(); - - // Assert - Assert.IsInstanceOfType(encoder); - } - - [TestMethod] - public void Add_PolylineDecoder_Test() { - // Arrange - var provider = Services - .BuildServiceProvider(); - - // Act - var decoder = provider - .GetRequiredService(); - - // Assert - Assert.IsInstanceOfType(decoder); - } - } -} \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs b/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs index dc3c768b..aa59c4f7 100644 --- a/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs +++ b/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs @@ -1,55 +1,55 @@ // -// Copyright (c) Petr Å rámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Tests { - using PolylineAlgorithm; +namespace PolylineAlgorithm.Tests; + +using PolylineAlgorithm; + +/// +/// Defines the +/// +[TestClass] +[TestCategory(nameof(CoordinateValidator))] +public class CoordinateValidatorTestCoordinate { + private static CoordinateValidator Validator { get; } = new CoordinateValidator(); + + #region Methods /// - /// Defines the + /// The IsValid_InvalidInput /// - [TestClass] - [TestCategory(nameof(CoordinateValidator))] - public class CoordinateValidatorTestCoordinate { - private static CoordinateValidator Validator { get; } = new CoordinateValidator(); - - #region Methods - - /// - /// The IsValid_InvalidInput - /// - [TestMethod] - public void IsValid_InvalidInput_IsFalse() { - // Act - var invalidCoordinateCollection = Defaults.Coordinate.Invalid; - - foreach (var item in invalidCoordinateCollection) { - // Arrange - var result = Validator.IsValid(item); - - // Assert - Assert.IsFalse(result); - } - } + [TestMethod] + public void IsValid_InvalidInput_IsFalse() { + // Act + var invalidCoordinateCollection = Defaults.Coordinate.Invalid; + + foreach (var item in invalidCoordinateCollection) { + // Arrange + var result = Validator.IsValid(item); - /// - /// The IsValid_ValidInput - /// - [TestMethod] - public void IsValid_ValidInput_IsTrue() { - // Act - var validCoordinateCollection = Defaults.Coordinate.Valid; - - foreach (var item in validCoordinateCollection) { - // Arrange - var result = Validator.IsValid(item); - - // Assert - Assert.IsTrue(result); - } + // Assert + Assert.IsFalse(result); } + } - #endregion + /// + /// The IsValid_ValidInput + /// + [TestMethod] + public void IsValid_ValidInput_IsTrue() { + // Act + var validCoordinateCollection = Defaults.Coordinate.Valid; + + foreach (var item in validCoordinateCollection) { + // Arrange + var result = Validator.IsValid(item); + + // Assert + Assert.IsTrue(result); + } } + + #endregion } diff --git a/tests/PolylineAlgorithm.Tests/Defaults.cs b/tests/PolylineAlgorithm.Tests/Defaults.cs index f7e55538..f2229688 100644 --- a/tests/PolylineAlgorithm.Tests/Defaults.cs +++ b/tests/PolylineAlgorithm.Tests/Defaults.cs @@ -1,64 +1,64 @@ // -// Copyright (c) Petr Å rámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Tests { - using System; - using System.Collections.Generic; +namespace PolylineAlgorithm.Tests; +using System; +using System.Collections.Generic; + +/// +/// Defines default values and objects used for testing purposes +/// +public static class Defaults { /// - /// Defines default values and objects used for testing purposes + /// Defines default decoded values and objects udÅ›ed for testing purposes /// - public static class Defaults { + public static class Coordinate { /// - /// Defines default decoded values and objects udÅ›ed for testing purposes + /// Defines empty range of coordinates. Equals to decoded /// - public static class Coordinate { - /// - /// Defines empty range of coordinates. Equals to decoded - /// - public static readonly IEnumerable<(double Latitude, double Longitude)> Empty = []; + public static readonly IEnumerable<(double Latitude, double Longitude)> Empty = []; - /// - /// Defines range of invalid coordinates. Equals to decoded - /// - public static readonly IEnumerable<(double Latitude, double Longitude)> Invalid = [ - (149.47383, 259.06250), - (-158.37407, 225.31250), - (152.99363, -220.93750), - (-144.49024, -274.37500) - ]; + /// + /// Defines range of invalid coordinates. Equals to decoded + /// + public static readonly IEnumerable<(double Latitude, double Longitude)> Invalid = [ + (149.47383, 259.06250), + (-158.37407, 225.31250), + (152.99363, -220.93750), + (-144.49024, -274.37500) + ]; - /// - /// Defines range of valid coordinates. Equals to decoded - /// - public static readonly IEnumerable<(double Latitude, double Longitude)> Valid = [ - (49.47383, 59.06250), - (-58.37407, 25.31250), - (52.99363, -120.93750), - (-44.49024, -174.37500) - ]; - } + /// + /// Defines range of valid coordinates. Equals to decoded + /// + public static readonly IEnumerable<(double Latitude, double Longitude)> Valid = [ + (49.47383, 59.06250), + (-58.37407, 25.31250), + (52.99363, -120.93750), + (-44.49024, -174.37500) + ]; + } + /// + /// Defines default encoded values and objects udÅ›ed for testing purposes + /// + public static class Polyline { /// - /// Defines default encoded values and objects udÅ›ed for testing purposes + /// Defines empty string of polyline encoded coordinates. Equals to encoded /// - public static class Polyline { - /// - /// Defines empty string of polyline encoded coordinates. Equals to encoded - /// - public static readonly string Empty = String.Empty; + public static readonly string Empty = String.Empty; - /// - /// Defines polyline encoded range of invalid coordinates. Equals to encoded - /// - public static readonly string Invalid = "mnc~Qsm_ja@"; + /// + /// Defines polyline encoded range of invalid coordinates. Equals to encoded + /// + public static readonly string Invalid = "mnc~Qsm_ja@"; - /// - /// Defines polyline encoded range of valid coordinates. Equals to encoded - /// - public static readonly string Valid = "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; - } + /// + /// Defines polyline encoded range of valid coordinates. Equals to encoded + /// + public static readonly string Valid = "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; } } diff --git a/tests/PolylineAlgorithm.Tests/GlobalSuppressions.cs b/tests/PolylineAlgorithm.Tests/GlobalSuppressions.cs index dfd5bb25..0b97243b 100644 --- a/tests/PolylineAlgorithm.Tests/GlobalSuppressions.cs +++ b/tests/PolylineAlgorithm.Tests/GlobalSuppressions.cs @@ -1,7 +1,7 @@ -// This file is used by Code Analysis to maintain SuppressMessage -// attributes that are applied to this project. -// Project-level suppressions either have no target or are given -// a specific target and scoped to a namespace, type, member, etc. +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// using System.Diagnostics.CodeAnalysis; diff --git a/tests/PolylineAlgorithm.Tests/GlobalUsings.cs b/tests/PolylineAlgorithm.Tests/GlobalUsings.cs index 2b506c25..8280b9af 100644 --- a/tests/PolylineAlgorithm.Tests/GlobalUsings.cs +++ b/tests/PolylineAlgorithm.Tests/GlobalUsings.cs @@ -1,5 +1,5 @@ // -// Copyright (c) Petr Šrámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // diff --git a/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs b/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs index d18e98e3..4d0b8429 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs +++ b/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs @@ -1,67 +1,67 @@ // -// Copyright (c) Petr Šrámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Tests { - /// - /// Defines the - /// - [TestClass] - [TestCategory(nameof(PolylineDecoder))] - public class PolylineDecoderTest { - private static PolylineDecoder Decoder { get; } = new PolylineDecoder(new CoordinateValidator()); +namespace PolylineAlgorithm.Tests; - /// - /// Method is testing method. Empty [] is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Decode_EmptyInput_ThrowsException() { - // Arrange - var emptyPolylineCharArray = Defaults.Polyline.Empty; +/// +/// Defines the +/// +[TestClass] +[TestCategory(nameof(PolylineDecoder))] +public class PolylineDecoderTest { + private static PolylineDecoder Decoder { get; } = new PolylineDecoder(new CoordinateValidator()); - // Act - void DecodeEmptyPolylineCharArray() { - Decoder.Decode(emptyPolylineCharArray).ToArray(); - } + /// + /// Method is testing method. Empty [] is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Decode_EmptyInput_ThrowsException() { + // Arrange + var emptyPolylineCharArray = Defaults.Polyline.Empty; - // Assert - Assert.ThrowsException(() => DecodeEmptyPolylineCharArray()); + // Act + void DecodeEmptyPolylineCharArray() { + Decoder.Decode(emptyPolylineCharArray).ToArray(); } - /// - /// Method is testing method. [] with invalid coordinates is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Decode_InvalidInput_ThrowsException() { - // Arrange - var invalidPolylineCharrArray = Defaults.Polyline.Invalid; + // Assert + Assert.ThrowsException(DecodeEmptyPolylineCharArray); + } - // Act - void DecodeInvalidPolylineCharArray() { - Decoder.Decode(invalidPolylineCharrArray).ToArray(); - } + /// + /// Method is testing method. [] with invalid coordinates is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Decode_InvalidInput_ThrowsException() { + // Arrange + var invalidPolylineCharrArray = Defaults.Polyline.Invalid; - // Assert - Assert.ThrowsException(() => DecodeInvalidPolylineCharArray()); + // Act + void DecodeInvalidPolylineCharArray() { + Decoder.Decode(invalidPolylineCharrArray).ToArray(); } - /// - /// Method is testing method. [] with valid coordinates is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Decode_ValidInput_AreEquivalent() { - // Arrange - var validPolylineCharArray = Defaults.Polyline.Valid; + // Assert + Assert.ThrowsException(DecodeInvalidPolylineCharArray); + } + + /// + /// Method is testing method. [] with valid coordinates is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Decode_ValidInput_AreEquivalent() { + // Arrange + var validPolylineCharArray = Defaults.Polyline.Valid; - // Act - var result = Decoder.Decode(validPolylineCharArray); + // Act + var result = Decoder.Decode(validPolylineCharArray); - // Assert - CollectionAssert.AreEquivalent(Defaults.Coordinate.Valid.ToList(), result.ToList()); - } + // Assert + CollectionAssert.AreEquivalent(Defaults.Coordinate.Valid.ToList(), result.ToList()); } } diff --git a/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs b/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs index f5ab7234..cad05d5e 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs +++ b/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs @@ -1,83 +1,83 @@ // -// Copyright (c) Petr Šrámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Tests { - /// - /// Defines the - /// - [TestClass] - [TestCategory(nameof(PolylineEncoder))] - public class PolylineEncoderTest { - private static PolylineEncoder Encoder { get; } = new PolylineEncoder(new CoordinateValidator()); +namespace PolylineAlgorithm.Tests; - /// - /// Method is testing method. Empty is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Encode_EmptyInput_ThrowsException() { - // Arrange - var emptyCoordinates = Defaults.Coordinate.Empty; +/// +/// Defines the +/// +[TestClass] +[TestCategory(nameof(PolylineEncoder))] +public class PolylineEncoderTest { + private static PolylineEncoder Encoder { get; } = new PolylineEncoder(new CoordinateValidator()); - // Act - void EncodeEmptyCoordinates() { - Encoder.Encode(emptyCoordinates); - } + /// + /// Method is testing method. Empty is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Encode_EmptyInput_ThrowsException() { + // Arrange + var emptyCoordinates = Defaults.Coordinate.Empty; - // Assert - Assert.ThrowsException(() => EncodeEmptyCoordinates()); + // Act + void EncodeEmptyCoordinates() { + Encoder.Encode(emptyCoordinates); } - /// - /// The Encode_InvalidInput - /// - [TestMethod] - public void Encode_InvalidInput_ThrowsException() { - // Arrange - var invalidCoordinates = Defaults.Coordinate.Invalid; + // Assert + Assert.ThrowsException(() => EncodeEmptyCoordinates()); + } - // Act - void EncodeInvalidCoordinates() { - Encoder.Encode(invalidCoordinates); - } + /// + /// The Encode_InvalidInput + /// + [TestMethod] + public void Encode_InvalidInput_ThrowsException() { + // Arrange + var invalidCoordinates = Defaults.Coordinate.Invalid; - // Assert - Assert.ThrowsException(() => EncodeInvalidCoordinates()); + // Act + void EncodeInvalidCoordinates() { + Encoder.Encode(invalidCoordinates); } - /// - /// Method is testing method. is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Encode_NullInput_ThrowsException() { - // Arrange - var nullCoordinates = (IEnumerable<(double, double)>)null!; + // Assert + Assert.ThrowsException(() => EncodeInvalidCoordinates()); + } - // Act - void EncodeNullCoordinates() { - Encoder.Encode(nullCoordinates); - } + /// + /// Method is testing method. is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Encode_NullInput_ThrowsException() { + // Arrange + var nullCoordinates = (IEnumerable<(double, double)>)null!; - // Assert - Assert.ThrowsException(() => EncodeNullCoordinates()); + // Act + void EncodeNullCoordinates() { + Encoder.Encode(nullCoordinates); } - /// - /// The Encode_ValidInput - /// - [TestMethod] - public void Encode_ValidInput_AreEqual() { - // Arrange - var validCoordinates = Defaults.Coordinate.Valid; + // Assert + Assert.ThrowsException(() => EncodeNullCoordinates()); + } - // Act - var result = Encoder.Encode(validCoordinates); + /// + /// The Encode_ValidInput + /// + [TestMethod] + public void Encode_ValidInput_AreEqual() { + // Arrange + var validCoordinates = Defaults.Coordinate.Valid; - // Assert - Assert.AreEqual(Defaults.Polyline.Valid, result); - } + // Act + var result = Encoder.Encode(validCoordinates); + + // Assert + Assert.AreEqual(Defaults.Polyline.Valid, result); } } diff --git a/tests/PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs b/tests/PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs index e517ce6d..aae125e3 100644 --- a/tests/PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs +++ b/tests/PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs @@ -1,5 +1,5 @@ // -// Copyright (c) Petr Å rámek. All rights reserved. +// Copyright (c) Pete Sramek. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for full license information. // diff --git a/tests/Validation/CoordinateValidatorTest.cs b/tests/Validation/CoordinateValidatorTest.cs deleted file mode 100644 index c36946ea..00000000 --- a/tests/Validation/CoordinateValidatorTest.cs +++ /dev/null @@ -1,132 +0,0 @@ -// -// Copyright (c) Petr Å rámek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Tests.Validation -{ - using PolylineAlgorithm.Validation; - using Microsoft.VisualStudio.TestTools.UnitTesting; - - /// - /// Defines the - /// - [TestClass] - [TestCategory(nameof(CoordinateValidator))] - public class CoordinateValidatorTest - { - /// - /// The IsValid_InvalidInput - /// - [TestMethod] - public void IsValid_InvalidInput_IsFalse() - { - // Act - var invalidCoordinateCollection = Defaults.Coordinate.Invalid; - - foreach (var item in invalidCoordinateCollection) - { - // Arrange - var result = CoordinateValidator.IsValid(item); - - // Assert - Assert.IsFalse(result); - } - } - - /// - /// The IsValid_ValidInput - /// - [TestMethod] - public void IsValid_ValidInput_IsTrue() - { - // Act - var validCoordinateCollection = Defaults.Coordinate.Valid; - - foreach (var item in validCoordinateCollection) - { - // Arrange - var result = CoordinateValidator.IsValid(item); - - // Assert - Assert.IsTrue(result); - } - } - - /// - /// The IsValidLatitude_InvalidInput - /// - [TestMethod] - public void IsValidLatitude_InvalidInput_IsFalse() - { - // Act - var invalidCoordinateCollection = Defaults.Coordinate.Invalid; - - foreach (var item in invalidCoordinateCollection) - { - // Act - var result = CoordinateValidator.IsValidLatitude(item.Latitude); - - // Arrange - Assert.IsFalse(result); - } - } - - /// - /// The IsValidLatitude_ValidInput - /// - [TestMethod] - public void IsValidLatitude_ValidInput_IsTrue() - { - // Arrange - var validCoordinateCollection = Defaults.Coordinate.Valid; - - foreach ((double Latitude, double Longitude) in validCoordinateCollection) - { - // Act - var result = CoordinateValidator.IsValidLatitude(Latitude); - - // Assert - Assert.IsTrue(result); - } - } - - /// - /// The IsValidLongitude_InvalidInput - /// - [TestMethod] - public void IsValidLongitude_InvalidInput_IsFalse() - { - // Arrange - var invalidCoordinateCollection = Defaults.Coordinate.Invalid; - - foreach (var item in invalidCoordinateCollection) - { - // Act - var result = CoordinateValidator.IsValidLongitude(item.Longitude); - - // Assert - Assert.IsFalse(result); - } - } - - /// - /// The IsValidLongitude_ValidInput - /// - [TestMethod] - public void IsValidLongitude_ValidInput_IsTrue() - { - // Arrange - var validCoordinateCollection = Defaults.Coordinate.Valid; - - foreach (var item in validCoordinateCollection) - { - // Act - var result = CoordinateValidator.IsValidLongitude(item.Longitude); - - // Assert - Assert.IsTrue(result); - } - } - } -} From 86c6c5f0c20a18bd909bb1c8f8b5fb59632e63d6 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Fri, 17 Jan 2025 00:31:33 +0100 Subject: [PATCH 036/352] restructured PolylineAlgorithm project --- README.md | 33 ++++++------------- .../PolylineDecoderBenchmark.cs | 1 + .../PolylineEncoderBenchmark.cs | 1 + .../ContainerBuilderExtensions.cs | 1 + .../ServiceCollectionExtensions.cs | 1 + .../{ => Abstraction}/ICoordinateValidator.cs | 2 +- .../{ => Abstraction}/IPolylineDecoder.cs | 2 +- .../{ => Abstraction}/IPolylineEncoder.cs | 2 +- src/PolylineAlgorithm/CoordinateValidator.cs | 1 + src/PolylineAlgorithm/PolylineDecoder.cs | 1 + src/PolylineAlgorithm/PolylineEncoder.cs | 1 + .../ContainerBuilderExtensionsTests.cs | 1 + .../ServiceCollectionExtensionsTests.cs | 1 + 13 files changed, 22 insertions(+), 26 deletions(-) rename src/PolylineAlgorithm/{ => Abstraction}/ICoordinateValidator.cs (94%) rename src/PolylineAlgorithm/{ => Abstraction}/IPolylineDecoder.cs (94%) rename src/PolylineAlgorithm/{ => Abstraction}/IPolylineEncoder.cs (95%) diff --git a/README.md b/README.md index 2695d8c8..afbc48ce 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@ Lightweight .NET Standard 2.0 library implementing Google Polyline Algorithm. Designed with respect to flexibility, but still with easy to use. -## Getting started -### Prerequisites +## Prerequisites .NET Polyline Algorithm is avalable as nuget package Cloudikka.PolylineAlgorithm targeting .NET Standard 2.0. @@ -15,34 +14,22 @@ NuGet Package Manager: `Cloudikka.PolylineAlgorithm` -#### Warning - -Library is using ValueTuple Structure. ValueTuple struct is avalable in .NET Framework 4.7 and above. Incase your project is targeting lower version of .NET Framework you probably have to install System.ValueTuple NuGet package. (not tested yet) - -Command line: - -`Install-Package System.ValueTuple` - -NuGet Package Manager: - -`System.ValueTuple` - -### Hot to use it +## Hot to use it There are three ways how to use .NET Polyline Algorithm library based on your needs. For each is available Encode and Decode methods. -#### Static methods +### Static methods Whenever you just need to encode or decode Google polyline you can use static methods defined in static PolylineAlgorithm class. -##### Decoding +#### Decoding ```csharp string polyline = "polyline"; IEnumerable<(double, double)> coordinates = PolylineAlgorithm.Decode(polyline); ``` -##### Encoding +#### Encoding ```csharp IEnumerable<(double, double)> coordinates = new (double, double) [] { (35.635, 76.27182), (35.2435, 75.625), ... }; @@ -50,11 +37,11 @@ Whenever you just need to encode or decode Google polyline you can use static me ``` -#### Default instance +### Default instance If you need to use dependency injection, you would like to have instance to deliver the work for you. In that case you can use default instance of PolylineEncoding class, which implements IPolylineEncoding<(double Latitude, double Longitude)> interface. -##### Decoding +#### Decoding ```csharp string polyline = "polyline"; @@ -62,7 +49,7 @@ If you need to use dependency injection, you would like to have instance to deli IEnumerable<(double, double)> coordinates = encoding.Decode(polyline); ``` -##### Encoding +#### Encoding ```csharp IEnumerable<(double, double)> coordinates = new (double, double) [] { (35.635, 76.27182), (35.2435, 75.625), ... }; @@ -70,11 +57,11 @@ If you need to use dependency injection, you would like to have instance to deli string polyline = encoding.Encode(coordinates); ``` -#### Inherited base class +### Inherited base class There may be a scenario you need to pass and return different types to and from without a need to add another extra layer. In this case you can inherit PolylineEncodingBase class and override template methods CreateResult and GetCoordinates. -##### Inheriting +#### Inheriting ```csharp public class MyPolylineEncoding : PolylineEncodingBase { diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs index 2f3a76fd..935fc112 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs @@ -8,6 +8,7 @@ namespace PolylineAlgorithm.Benchmarks; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; using BenchmarkDotNet.Order; +using PolylineAlgorithm.Abstraction; [MemoryDiagnoser] [MarkdownExporter] diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs index 06bdaf83..0049e3d8 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs @@ -8,6 +8,7 @@ namespace PolylineAlgorithm.Benchmarks; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; using BenchmarkDotNet.Order; +using PolylineAlgorithm.Abstraction; [MemoryDiagnoser] [MarkdownExporter] diff --git a/src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs b/src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs index 866bb63b..9ffdae03 100644 --- a/src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs +++ b/src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs @@ -6,6 +6,7 @@ namespace PolylineAlgorithm.DependencyInjection.Autofac; using global::Autofac; +using PolylineAlgorithm.Abstraction; public static class ContainerBuilderExtensions { /// diff --git a/src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs b/src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs index cc371bb4..4c7c9d47 100644 --- a/src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs +++ b/src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs @@ -6,6 +6,7 @@ namespace PolylineAlgorithm.DependencyInjection.Microsoft; using global::Microsoft.Extensions.DependencyInjection; +using PolylineAlgorithm.Abstraction; public static class ServiceCollectionExtensions { /// diff --git a/src/PolylineAlgorithm/ICoordinateValidator.cs b/src/PolylineAlgorithm/Abstraction/ICoordinateValidator.cs similarity index 94% rename from src/PolylineAlgorithm/ICoordinateValidator.cs rename to src/PolylineAlgorithm/Abstraction/ICoordinateValidator.cs index 9d95ce25..08752927 100644 --- a/src/PolylineAlgorithm/ICoordinateValidator.cs +++ b/src/PolylineAlgorithm/Abstraction/ICoordinateValidator.cs @@ -3,7 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm; +namespace PolylineAlgorithm.Abstraction; /// /// Provides validation of a coordinate value. diff --git a/src/PolylineAlgorithm/IPolylineDecoder.cs b/src/PolylineAlgorithm/Abstraction/IPolylineDecoder.cs similarity index 94% rename from src/PolylineAlgorithm/IPolylineDecoder.cs rename to src/PolylineAlgorithm/Abstraction/IPolylineDecoder.cs index 17ebaa75..250a4aee 100644 --- a/src/PolylineAlgorithm/IPolylineDecoder.cs +++ b/src/PolylineAlgorithm/Abstraction/IPolylineDecoder.cs @@ -3,7 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm; +namespace PolylineAlgorithm.Abstraction; using System.Collections.Generic; diff --git a/src/PolylineAlgorithm/IPolylineEncoder.cs b/src/PolylineAlgorithm/Abstraction/IPolylineEncoder.cs similarity index 95% rename from src/PolylineAlgorithm/IPolylineEncoder.cs rename to src/PolylineAlgorithm/Abstraction/IPolylineEncoder.cs index 541f514d..5ff66ac6 100644 --- a/src/PolylineAlgorithm/IPolylineEncoder.cs +++ b/src/PolylineAlgorithm/Abstraction/IPolylineEncoder.cs @@ -3,7 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm; +namespace PolylineAlgorithm.Abstraction; using System.Collections.Generic; diff --git a/src/PolylineAlgorithm/CoordinateValidator.cs b/src/PolylineAlgorithm/CoordinateValidator.cs index b9d125de..3f47c3e5 100644 --- a/src/PolylineAlgorithm/CoordinateValidator.cs +++ b/src/PolylineAlgorithm/CoordinateValidator.cs @@ -5,6 +5,7 @@ namespace PolylineAlgorithm; +using PolylineAlgorithm.Abstraction; using PolylineAlgorithm.Internal; /// diff --git a/src/PolylineAlgorithm/PolylineDecoder.cs b/src/PolylineAlgorithm/PolylineDecoder.cs index 4f8b2ddc..607d0da0 100644 --- a/src/PolylineAlgorithm/PolylineDecoder.cs +++ b/src/PolylineAlgorithm/PolylineDecoder.cs @@ -5,6 +5,7 @@ namespace PolylineAlgorithm; +using PolylineAlgorithm.Abstraction; using PolylineAlgorithm.Internal; /// diff --git a/src/PolylineAlgorithm/PolylineEncoder.cs b/src/PolylineAlgorithm/PolylineEncoder.cs index f4af4ed9..70d15b9b 100644 --- a/src/PolylineAlgorithm/PolylineEncoder.cs +++ b/src/PolylineAlgorithm/PolylineEncoder.cs @@ -5,6 +5,7 @@ namespace PolylineAlgorithm; +using PolylineAlgorithm.Abstraction; using PolylineAlgorithm.Internal; using System; using System.Collections.Generic; diff --git a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs index bfd87e10..af984005 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs @@ -5,6 +5,7 @@ namespace PolylineAlgorithm.DependencyInjection.Autofac.Tests; +using PolylineAlgorithm.Abstraction; using PolylineAlgorithm.DependencyInjection.Autofac; [TestClass] diff --git a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs index fc11ae84..4969faa0 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs @@ -5,6 +5,7 @@ namespace PolylineAlgorithm.DependencyInjection.Tests; +using PolylineAlgorithm.Abstraction; using PolylineAlgorithm.DependencyInjection.Microsoft; [TestClass] From 741f4677774b9e9cbeeff41805506603da50493c Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 22 Jan 2025 23:12:33 +0100 Subject: [PATCH 037/352] refactored --- PolylineAlgorithm.sln | 7 + .../PolylineAlgorithm.Benchmarks.csproj | 2 +- .../PolylineBenchmark.cs | 41 +++ .../PolylineDecoderBenchmark.cs | 37 -- .../PolylineEncoderBenchmark.cs | 37 -- .../PolylineAlgorithm.Benchmarks/Program.cs | 4 +- ...Algorithm.Implementation.Benchmarks.csproj | 5 +- .../PolylineDecoderBenchmark.cs.cs | 202 ++++++----- .../PolylineEncoderBenchmark.cs | 326 ++++++++++-------- .../Program.cs | 3 +- .../ContainerBuilderExtensions.cs | 25 +- .../ServiceCollectionExtensions.cs | 22 +- .../NetTopologyPolylineDecoder.cs | 11 + .../NetTopologyPolylineEncoder.cs | 20 ++ .../PolylineAlgorithm.NetTopologySuite.csproj | 27 ++ .../Abstraction/ICoordinateValidator.cs | 18 - .../Abstraction/IPolylineDecoder.cs | 12 +- .../Abstraction/IPolylineEncoder.cs | 4 +- .../Abstraction/PolylineDecoder.cs | 84 +++++ .../Abstraction/PolylineEncoder.cs | 90 +++++ src/PolylineAlgorithm/Coordinate.cs | 89 +++++ .../CoordinateValidationException.cs | 37 -- src/PolylineAlgorithm/CoordinateValidator.cs | 34 -- .../DefaultPolylineDecoder.cs | 15 + .../DefaultPolylineEncoder.cs | 21 ++ src/PolylineAlgorithm/Internal/Constants.cs | 42 +-- .../ExceptionMessageResource.Designer.cs | 14 +- .../ExceptionMessageResource.resx | 6 +- src/PolylineAlgorithm/Polyline.cs | 61 ++++ .../PolylineAlgorithm.csproj | 4 +- src/PolylineAlgorithm/PolylineDecoder.cs | 83 ----- src/PolylineAlgorithm/PolylineEncoder.cs | 103 ------ .../ContainerBuilderExtensionsTests.cs | 23 +- .../ServiceCollectionExtensionsTests.cs | 26 +- .../CoordinateValidatorTest.cs | 55 --- tests/PolylineAlgorithm.Tests/Defaults.cs | 32 +- .../PolylineDecoderTest.cs | 30 +- .../PolylineEncoderTest.cs | 30 +- 38 files changed, 871 insertions(+), 811 deletions(-) create mode 100644 benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs delete mode 100644 benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs delete mode 100644 benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs create mode 100644 src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineDecoder.cs create mode 100644 src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineEncoder.cs create mode 100644 src/PolylineAlgorithm.NetTopologySuite/PolylineAlgorithm.NetTopologySuite.csproj delete mode 100644 src/PolylineAlgorithm/Abstraction/ICoordinateValidator.cs create mode 100644 src/PolylineAlgorithm/Abstraction/PolylineDecoder.cs create mode 100644 src/PolylineAlgorithm/Abstraction/PolylineEncoder.cs create mode 100644 src/PolylineAlgorithm/Coordinate.cs delete mode 100644 src/PolylineAlgorithm/CoordinateValidationException.cs delete mode 100644 src/PolylineAlgorithm/CoordinateValidator.cs create mode 100644 src/PolylineAlgorithm/DefaultPolylineDecoder.cs create mode 100644 src/PolylineAlgorithm/DefaultPolylineEncoder.cs rename src/PolylineAlgorithm/{ => Internal}/ExceptionMessageResource.Designer.cs (90%) rename src/PolylineAlgorithm/{ => Internal}/ExceptionMessageResource.resx (96%) create mode 100644 src/PolylineAlgorithm/Polyline.cs delete mode 100644 src/PolylineAlgorithm/PolylineDecoder.cs delete mode 100644 src/PolylineAlgorithm/PolylineEncoder.cs delete mode 100644 tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs diff --git a/PolylineAlgorithm.sln b/PolylineAlgorithm.sln index 41fcfe71..77423ead 100644 --- a/PolylineAlgorithm.sln +++ b/PolylineAlgorithm.sln @@ -31,6 +31,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolylineAlgorithm.Dependenc EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolylineAlgorithm.DependencyInjection.Microsoft", "src\PolylineAlgorithm.DependencyInjection.Microsoft\PolylineAlgorithm.DependencyInjection.Microsoft.csproj", "{2B0061B3-7B80-4101-9FF0-AD513AE4C4E5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolylineAlgorithm.NetTopologySuite", "src\PolylineAlgorithm.NetTopologySuite\PolylineAlgorithm.NetTopologySuite.csproj", "{A5F4D456-3949-4146-95D2-E0208EEF207A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -69,6 +71,10 @@ Global {2B0061B3-7B80-4101-9FF0-AD513AE4C4E5}.Debug|Any CPU.Build.0 = Debug|Any CPU {2B0061B3-7B80-4101-9FF0-AD513AE4C4E5}.Release|Any CPU.ActiveCfg = Release|Any CPU {2B0061B3-7B80-4101-9FF0-AD513AE4C4E5}.Release|Any CPU.Build.0 = Release|Any CPU + {A5F4D456-3949-4146-95D2-E0208EEF207A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A5F4D456-3949-4146-95D2-E0208EEF207A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A5F4D456-3949-4146-95D2-E0208EEF207A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A5F4D456-3949-4146-95D2-E0208EEF207A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -82,6 +88,7 @@ Global {F9CFF4B1-C9AB-4F94-ADF4-B29925E1187E} = {576FEFFC-B624-40C3-A8AF-4E5233802EA0} {9C1088DA-DBF7-4374-9775-C7613CCA98D8} = {51C886AF-D610-48A4-9D73-2DEB38742801} {2B0061B3-7B80-4101-9FF0-AD513AE4C4E5} = {51C886AF-D610-48A4-9D73-2DEB38742801} + {A5F4D456-3949-4146-95D2-E0208EEF207A} = {51C886AF-D610-48A4-9D73-2DEB38742801} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {93A268DC-0947-4FBB-B495-DDAD4B013D82} diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj index 5a8572fc..f4b46667 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj @@ -2,7 +2,7 @@ Exe - net9.0 + net5.0;net6.0;net7.0;net8.0;net9.0 13.0 enable enable diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs new file mode 100644 index 00000000..74990643 --- /dev/null +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs @@ -0,0 +1,41 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Benchmarks; + +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Jobs; +using System.Collections.Generic; + +[RankColumn] +[MemoryDiagnoser] +[SimpleJob(RuntimeMoniker.Net50, baseline: true)] +[SimpleJob(RuntimeMoniker.Net60)] +[SimpleJob(RuntimeMoniker.Net70)] +[SimpleJob(RuntimeMoniker.Net80)] +[SimpleJob(RuntimeMoniker.Net90)] +[Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.Declared)] +public class PolylineBenchmark { + private readonly Consumer _consumer = new(); + + public DefaultPolylineDecoder Decoder { get; } = new DefaultPolylineDecoder(); + public Polyline Polyline { get; } = new Polyline("}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"); + + [Benchmark] + public Span Decode() + => Decoder + .Decode(Polyline); + + public DefaultPolylineEncoder Encoder { get; } = new DefaultPolylineEncoder(); + + public IEnumerable Coordinates { get; } = [Coordinate.Create(60.81071, -121.40005), Coordinate.Create(70.05664, -38.43130), Coordinate.Create(37.52379, -84.83755), Coordinate.Create(41.85003, 26.25620), Coordinate.Create(68.04709, 110.63120), Coordinate.Create(61.48922, 50.16245), Coordinate.Create(-4.46018, -58.11880), Coordinate.Create(-32.16061, -3.27505), Coordinate.Create(-50.89185, -55.30630), Coordinate.Create(-28.52070, 90.94370), Coordinate.Create(35.26009, 93.75620), Coordinate.Create(54.83622, 128.91245), Coordinate.Create(1.16022, 37.50620), Coordinate.Create(-44.26398, -131.24380), Coordinate.Create(-33.34325, 154.22495), Coordinate.Create(-59.65879, 90.94370), Coordinate.Create(-62.38215, 0.94370), Coordinate.Create(72.32117, 40.31870), Coordinate.Create(64.66910, 2.34995), Coordinate.Create(-61.04971, -84.83755), Coordinate.Create(77.10238, -91.86880), Coordinate.Create(-72.88859, -129.83755), Coordinate.Create(-69.24987, -24.36880), Coordinate.Create(77.41254, 119.06870), Coordinate.Create(-70.69409, 83.91245), Coordinate.Create(78.85650, 75.47495), Coordinate.Create(26.83989, 140.16245), Coordinate.Create(-24.75069, -108.74380), Coordinate.Create(30.53968, -145.30630), Coordinate.Create(79.12503, 145.78745), Coordinate.Create(-34.51006, 133.13120), Coordinate.Create(-73.29753, -60.93130), Coordinate.Create(-74.08712, 23.44370), Coordinate.Create(-76.57404, 100.78745), Coordinate.Create(-76.57404, 100.78745), Coordinate.Create(39.72082, 103.59995), Coordinate.Create(70.99412, 148.59995), Coordinate.Create(82.27591, 138.75620), Coordinate.Create(78.29964, -3.27505), Coordinate.Create(78.29964, -3.27505), Coordinate.Create(-8.65039, 47.34995)]; + + + [Benchmark] + public Polyline Encode() + => Encoder + .Encode(Coordinates); +} diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs deleted file mode 100644 index 935fc112..00000000 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Benchmarks; - -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; -using BenchmarkDotNet.Order; -using PolylineAlgorithm.Abstraction; - -[MemoryDiagnoser] -[MarkdownExporter] -[Orderer(SummaryOrderPolicy.FastestToSlowest)] -public class PolylineDecoderBenchmark { - private readonly Consumer _consumer = new(); - - public required IPolylineDecoder Decoder { get; set; } - - public static IEnumerable GetPolylines() { - yield return "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; - yield return "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; - yield return "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"; - } - - [GlobalSetup] - public void Setup() { - Decoder = new PolylineDecoder(new CoordinateValidator()); - } - - [Benchmark] - [ArgumentsSource(nameof(GetPolylines))] - public void Decode(string polyline) => Decoder - .Decode(polyline) - .Consume(_consumer); -} diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs deleted file mode 100644 index 0049e3d8..00000000 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Benchmarks; - -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; -using BenchmarkDotNet.Order; -using PolylineAlgorithm.Abstraction; - -[MemoryDiagnoser] -[MarkdownExporter] -[Orderer(SummaryOrderPolicy.FastestToSlowest)] -public class PolylineEncoderBenchmark { - private readonly Consumer _consumer = new(); - - public required IPolylineEncoder Encoder { get; set; } - - public static IEnumerable> GetCoordinates() { - yield return new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) }; - yield return new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }; - yield return new[] { (60.81071, -121.40005), (70.05664, -38.43130), (37.52379, -84.83755), (41.85003, 26.25620), (68.04709, 110.63120), (61.48922, 50.16245), (-4.46018, -58.11880), (-32.16061, -3.27505), (-50.89185, -55.30630), (-28.52070, 90.94370), (35.26009, 93.75620), (54.83622, 128.91245), (1.16022, 37.50620), (-44.26398, -131.24380), (-33.34325, 154.22495), (-59.65879, 90.94370), (-62.38215, 0.94370), (72.32117, 40.31870), (64.66910, 2.34995), (-61.04971, -84.83755), (77.10238, -91.86880), (-72.88859, -129.83755), (-69.24987, -24.36880), (77.41254, 119.06870), (-70.69409, 83.91245), (78.85650, 75.47495), (26.83989, 140.16245), (-24.75069, -108.74380), (30.53968, -145.30630), (79.12503, 145.78745), (-34.51006, 133.13120), (-73.29753, -60.93130), (-74.08712, 23.44370), (-76.57404, 100.78745), (-76.57404, 100.78745), (39.72082, 103.59995), (70.99412, 148.59995), (82.27591, 138.75620), (78.29964, -3.27505), (78.29964, -3.27505), (-8.65039, 47.34995) }; - } - - [GlobalSetup] - public void Setup() { - Encoder = new PolylineEncoder(new CoordinateValidator()); - } - - [Benchmark] - [ArgumentsSource(nameof(GetCoordinates))] - public void Encode(IEnumerable<(double, double)> coordinates) => Encoder - .Encode(coordinates) - .Consume(_consumer); -} diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index b8578882..87827e06 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -10,8 +10,6 @@ namespace PolylineAlgorithm.Benchmarks; internal class Program { static void Main(string[] _) { BenchmarkRunner - .Run(); - BenchmarkRunner - .Run(); + .Run(); } } diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj index 8f30bdbd..44c51b5b 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj @@ -2,12 +2,14 @@ Exe - net9.0 + net9.0 13.0 enable enable true en + pdbonly + true @@ -16,6 +18,7 @@ + diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs index 500fee2a..96a93276 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs @@ -6,113 +6,78 @@ namespace PolylineAlgorithm.Implementation.Benchmarks; using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; -using PolylineAlgorithm; +using BenchmarkDotNet.Diagnosers; +using BenchmarkDotNet.Order; using System; +using System.Collections.ObjectModel; using System.Runtime.CompilerServices; -[MemoryDiagnoser] [RankColumn] -[Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.Declared)] +[MemoryDiagnoser] +[RPlotExporter] +[EventPipeProfiler(EventPipeProfile.CpuSampling)] +[Orderer(SummaryOrderPolicy.Declared)] public class PolylineDecoderBenchmark { - private readonly Consumer _consumer = new(); - private readonly static CoordinateValidator _validator = new(); - public static IEnumerable Polylines() { - yield return "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; - yield return "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"; - yield return "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"; - } + public static Dictionary Values() => + new Dictionary { + {1, "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"}, + {2, "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"}, + {3, "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"} + }; + + [ParamsSource(nameof(Values))] + public KeyValuePair Polyline { get; set; } [Benchmark(Baseline = true)] - [ArgumentsSource(nameof(Polylines))] - public void Decode_Current(string polyline) => Current.Decode(polyline).Consume(_consumer); + public Span Decode_Current() { + var decoder = new DefaultPolylineDecoder(); + return decoder.Decode(new Polyline(Polyline.Value)); + } [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V1(string polyline) => V1.Decode(polyline).Consume(_consumer); + public (double, double)[] Decode_V1() { + var decoder = new V1(); + return decoder.Decode(Polyline.Value).ToArray(); + } [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V2(string polyline) => V2.Decode(polyline).Consume(_consumer); + public (double, double)[] Decode_V2() { + var decoder = new V2(); + return decoder.Decode(Polyline.Value).ToArray(); + } [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V3(string polyline) => V3.Decode(polyline).Consume(_consumer); + public (double, double)[] Decode_V3() { + var decoder = new V3(); + return decoder.Decode(Polyline.Value).ToArray(); + } [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V4(string polyline) => V4.Decode(polyline.AsMemory()).Consume(_consumer); + public (double, double)[] Decode_V4() { + var decoder = new V4(); + return decoder.Decode(Polyline.Value.AsMemory()).ToArray(); + } [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V5(string polyline) => V5.Decode(polyline).Consume(_consumer); + public (double, double)[] Decode_V5() { + var decoder = new V5(); + return decoder.Decode(Polyline.Value).ToArray(); + } [Benchmark] - [ArgumentsSource(nameof(Polylines))] - public void Decode_V6(string polyline) => V6.Default.Decode(polyline).Consume(_consumer); - - private class Current { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - // Checking null and at least one character - if (polyline == null || polyline.Length == 0) { - throw new ArgumentException(String.Empty, nameof(polyline)); - } - - // Initialize local variables - int index = 0; - int latitude = 0; - int longitude = 0; - - // Looping through encoded polyline char array - while (index < polyline.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref latitude)) { - throw new InvalidOperationException(String.Empty); - } - - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref longitude)) { - throw new InvalidOperationException(String.Empty); - } - - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - - // Validating decoded coordinate. If not valid exception is thrown - if (!_validator.IsValid(coordinate)) { - throw new InvalidOperationException(String.Empty); - } - - yield return coordinate; - } - } - - static bool TryCalculateNext(string polyline, ref int index, ref int value) { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } + public (double, double)[] Decode_V6() { + var decoder = new V6(); + return decoder.Decode(Polyline.Value).ToArray(); + } - static double GetCoordinate(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } + [Benchmark] + public (double, double)[] Decode_V7() { + var decoder = new V7(); + return decoder.Decode(Polyline.Value).ToArray(); } private class V1 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { if (polyline is null || polyline.Length == 0) { throw new ArgumentException(nameof(polyline)); } @@ -183,7 +148,7 @@ public static bool IsValidLongitude(double longitude) { } private class V2 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { if (polyline is null || polyline.Length == 0) { throw new ArgumentException(nameof(polyline)); } @@ -250,7 +215,7 @@ public static bool IsValidLongitude(double longitude) { } private class V3 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { // Checking null and at least one character if (polyline == null || polyline.Length == 0) { throw new ArgumentException(String.Empty, nameof(polyline)); @@ -343,7 +308,7 @@ public static bool IsValidLongitude(double longitude) { } private class V4 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(ReadOnlyMemory polyline) { + public IEnumerable<(double Latitude, double Longitude)> Decode(ReadOnlyMemory polyline) { // Checking null and at least one character if (polyline.IsEmpty) { throw new ArgumentException(String.Empty, nameof(polyline)); @@ -432,7 +397,7 @@ public static bool IsValidLongitude(double longitude) { } private class V5 { - public static IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { // Checking null and at least one character if (polyline == null || polyline.Length == 0) { throw new ArgumentException(String.Empty, nameof(polyline)); @@ -522,7 +487,6 @@ public static bool IsValidLongitude(double longitude) { } private class V6 { - public static V6 Default = new(); public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { // Checking null and at least one character if (polyline == null || polyline.Length == 0) { @@ -548,11 +512,6 @@ private class V6 { var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - // Validating decoded coordinate. If not valid exception is thrown - if (!_validator.IsValid(coordinate)) { - throw new InvalidOperationException(String.Empty); - } - yield return coordinate; } } @@ -581,4 +540,59 @@ private double GetCoordinate(int value) { return Convert.ToDouble(value) / Constants.Precision; } } + + private class V7 { + public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { + // Checking null and at least one character + if (polyline == null || polyline.Length == 0) { + throw new ArgumentException(string.Empty, nameof(polyline)); + } + + // Initialize local variables + int index = 0; + int latitude = 0; + int longitude = 0; + + // Looping through encoded polyline char array + while (index < polyline.Length) { + // Attempting to calculate next latitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref latitude)) { + throw new InvalidOperationException(string.Empty); + } + + // Attempting to calculate next longitude value. If failed exception is thrown + if (!TryCalculateNext(polyline, ref index, ref longitude)) { + throw new InvalidOperationException(string.Empty); + } + + var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); + + yield return coordinate; + } + } + + static bool TryCalculateNext(string polyline, ref int index, ref int value) { + // Local variable initialization + int chunk; + int sum = 0; + int shifter = 0; + + do { + chunk = polyline[index++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + + if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + static double GetCoordinate(int value) { + return Convert.ToDouble(value) / Constants.Precision; + } + } } diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs index f19ee966..256b95c9 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs @@ -6,166 +6,94 @@ namespace PolylineAlgorithm.Implementation.Benchmarks; using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Diagnosers; +using BenchmarkDotNet.Order; using Microsoft.Extensions.ObjectPool; using System.Collections.Generic; using System.Text; -[MemoryDiagnoser] [RankColumn] -[Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.Declared)] +[MemoryDiagnoser] +[RPlotExporter] +[EventPipeProfiler(EventPipeProfile.CpuSampling)] +[Orderer(SummaryOrderPolicy.Declared)] public class PolylineEncoderBenchmark { - public IEnumerable<(int, IEnumerable<(double, double)> coordinates)> Coordinates() { - yield return (1, new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) }); - yield return (2, new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) }); - yield return (3, new[] { (60.81071, -121.40005), (70.05664, -38.43130), (37.52379, -84.83755), (41.85003, 26.25620), (68.04709, 110.63120), (61.48922, 50.16245), (-4.46018, -58.11880), (-32.16061, -3.27505), (-50.89185, -55.30630), (-28.52070, 90.94370), (35.26009, 93.75620), (54.83622, 128.91245), (1.16022, 37.50620), (-44.26398, -131.24380), (-33.34325, 154.22495), (-59.65879, 90.94370), (-62.38215, 0.94370), (72.32117, 40.31870), (64.66910, 2.34995), (-61.04971, -84.83755), (77.10238, -91.86880), (-72.88859, -129.83755), (-69.24987, -24.36880), (77.41254, 119.06870), (-70.69409, 83.91245), (78.85650, 75.47495), (26.83989, 140.16245), (-24.75069, -108.74380), (30.53968, -145.30630), (79.12503, 145.78745), (-34.51006, 133.13120), (-73.29753, -60.93130), (-74.08712, 23.44370), (-76.57404, 100.78745), (-76.57404, 100.78745), (39.72082, 103.59995), (70.99412, 148.59995), (82.27591, 138.75620), (78.29964, -3.27505), (78.29964, -3.27505), (-8.65039, 47.34995) }); - } + + public Dictionary Values => + new Dictionary { + {1, new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) } }, + {2, new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) } }, + {3, new[] { (60.81071, -121.40005), (70.05664, -38.43130), (37.52379, -84.83755), (41.85003, 26.25620), (68.04709, 110.63120), (61.48922, 50.16245), (-4.46018, -58.11880), (-32.16061, -3.27505), (-50.89185, -55.30630), (-28.52070, 90.94370), (35.26009, 93.75620), (54.83622, 128.91245), (1.16022, 37.50620), (-44.26398, -131.24380), (-33.34325, 154.22495), (-59.65879, 90.94370), (-62.38215, 0.94370), (72.32117, 40.31870), (64.66910, 2.34995), (-61.04971, -84.83755), (77.10238, -91.86880), (-72.88859, -129.83755), (-69.24987, -24.36880), (77.41254, 119.06870), (-70.69409, 83.91245), (78.85650, 75.47495), (26.83989, 140.16245), (-24.75069, -108.74380), (30.53968, -145.30630), (79.12503, 145.78745), (-34.51006, 133.13120), (-73.29753, -60.93130), (-74.08712, 23.44370), (-76.57404, 100.78745), (-76.57404, 100.78745), (39.72082, 103.59995), (70.99412, 148.59995), (82.27591, 138.75620), (78.29964, -3.27505), (78.29964, -3.27505), (-8.65039, 47.34995) } } + }; + + + [ParamsSource(nameof(Values))] + public KeyValuePair Coordinates { get; set; } [Benchmark(Baseline = true)] - [ArgumentsSource(nameof(Coordinates))] - public string Encode_Current((int, IEnumerable<(double, double)> coordinates) value) => Current.Encode(value.coordinates); + public Polyline Encode_Current() { + var encoder = new DefaultPolylineEncoder(); + var result = encoder.Encode(Coordinates.Value.Select(v => Coordinate.Create(v.Item1, v.Item2))); + return result; + } [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public string Encode_V1((int, IEnumerable<(double, double)> coordinates) value) => V1.Encode(value.coordinates); + public string Encode_V1() { + var encoder = new V1(); + var result = encoder.Encode(Coordinates.Value); + return result; + } [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public string Encode_V2((int, IEnumerable<(double, double)> coordinates) value) => V2.Encode(value.coordinates); + [ArgumentsSource(nameof(Values))] + public string Encode_V2() { + var encoder = new V2(); + var result = encoder.Encode(Coordinates.Value); + return result; + } [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public string Encode_V3((int, IEnumerable<(double, double)> coordinates) value) => V3.Encode(value.coordinates); + [ArgumentsSource(nameof(Values))] + public string Encode_V3() { + var encoder = new V3(); + var result = encoder.Encode(Coordinates.Value); + return result; + } [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public string Encode_V4((int, IEnumerable<(double, double)> coordinates) value) => V4.Encode(value.coordinates); + [ArgumentsSource(nameof(Values))] + public string Encode_V4() { + var encoder = new V4(); + var result = encoder.Encode(Coordinates.Value); + return result; + } [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public string Encode_V5((int, IEnumerable<(double, double)> coordinates) value) => V5.Encode(value.coordinates); + [ArgumentsSource(nameof(Values))] + public string Encode_V5() { + var encoder = new V5(); + var result = encoder.Encode(Coordinates.Value); + return result; + } [Benchmark] - [ArgumentsSource(nameof(Coordinates))] - public string Encode_V6((int, IEnumerable<(double, double)> coordinates) value) => V6.Default.Encode(value.coordinates); - - private class Current { - /// - /// Method encodes coordinates to polyline encoded representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(); - } - - int count = coordinates.Count(); - ICollection exceptions = new List(count); - - // Validate collection of coordinates - if (!TryValidate(coordinates, ref exceptions)) { - throw new AggregateException(exceptions); - } - - // Initializing local variables - int index = 0; - Memory buffer = new char[count * 12]; - int previousLatitude = 0; - int previousLongitude = 0; - - // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(Latitude); - int longitude = Round(Longitude); - - WriteNext(ref buffer, ref index, ref latitude, ref previousLatitude); - WriteNext(ref buffer, ref index, ref longitude, ref previousLongitude); - } - - return buffer[..index].ToString(); - - #region Local functions - - static bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { - foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } - } - - return exceptions.Count == 0; - } - - static int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - static void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { - int value = current - previous; - int shifted = value << 1; - - if (value < 0) { - shifted = ~shifted; - } - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - rem >>= Constants.ShiftLength; - index++; - } - - buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); - - index++; - - previous = current; - } - #endregion - } - - public static class CoordinateValidator { - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - /// - /// Performs latitude validation - /// - /// Latitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - /// - /// Performs longitude validation - /// - /// Longitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - - public class CoordinateValidationException(double latitude, double longitude) - : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { - public double Latitude { get; } + [ArgumentsSource(nameof(Values))] + public string Encode_V6() { + var encoder = new V6(); + var result = encoder.Encode(Coordinates.Value); + return result; + } - public double Longitude { get; } - } + [Benchmark] + [ArgumentsSource(nameof(Values))] + public string Encode_V7() { + var encoder = new V7(); + var result = encoder.Encode(Coordinates.Value); + return result; } private class V1 { - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { if (coordinates is null || !coordinates.Any()) { throw new ArgumentException(nameof(coordinates)); } @@ -242,7 +170,7 @@ public static bool IsValidLongitude(double longitude) { private class V2 { private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, int.MaxValue); - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { if (coordinates is null || !coordinates.Any()) { throw new ArgumentException(nameof(coordinates)); } @@ -329,7 +257,7 @@ private class V3 { /// Polyline encoded representation /// If coordinates parameter is null or empty enumerable /// If one or more coordinate is out of range - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { throw new ArgumentException(); } @@ -442,7 +370,7 @@ private class V4 { /// Polyline encoded representation /// If coordinates parameter is null or empty enumerable /// If one or more coordinate is out of range - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { throw new ArgumentException(); } @@ -556,7 +484,7 @@ private class V5 { /// Polyline encoded representation /// If coordinates parameter is null or empty enumerable /// If one or more coordinate is out of range - public static string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { throw new ArgumentException(); } @@ -661,8 +589,6 @@ public class CoordinateValidationException(double latitude, double longitude) } private class V6 { - public static V6 Default = new(); - /// /// Method encodes coordinates to polyline encoded representation /// @@ -774,4 +700,120 @@ public class CoordinateValidationException(double latitude, double longitude) public double Longitude { get; } } } + + private class V7 { + /// + /// Method encodes coordinates to polyline encoded representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null or empty enumerable + /// If one or more coordinate is out of range + public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { + if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { + throw new ArgumentException(); + } + + int count = coordinates.Count(); + ICollection exceptions = new List(count); + + // Validate collection of coordinates + if (!TryValidate(coordinates, ref exceptions)) { + throw new AggregateException(exceptions); + } + + // Initializing local variables + int index = 0; + Memory buffer = new char[count * 12]; + int previousLatitude = 0; + int previousLongitude = 0; + + // Looping over coordinates and building encoded result + foreach (var (Latitude, Longitude) in coordinates) { + int latitude = Round(Latitude); + int longitude = Round(Longitude); + + WriteNext(ref buffer, ref index, ref latitude, ref previousLatitude); + WriteNext(ref buffer, ref index, ref longitude, ref previousLongitude); + } + + return buffer[..index].ToString(); + + #region Local functions + + static bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { + foreach (var item in collection) { + if (!CoordinateValidator.IsValid(item)) { + exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); + } + } + + return exceptions.Count == 0; + } + + static int Round(double value) { + return (int)Math.Round(value * Constants.Precision); + } + + static void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { + int value = current - previous; + int shifted = value << 1; + + if (value < 0) { + shifted = ~shifted; + } + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) { + buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + rem >>= Constants.ShiftLength; + index++; + } + + buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); + + index++; + + previous = current; + } + #endregion + } + + public static class CoordinateValidator { + /// + /// Performs coordinate validation + /// + /// Coordinate to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValid((double Latitude, double Longitude) coordinate) { + return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); + } + + /// + /// Performs latitude validation + /// + /// Latitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLatitude(double latitude) { + return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; + } + + /// + /// Performs longitude validation + /// + /// Longitude value to validate + /// Returns validation result. If valid then true, otherwise false. + public static bool IsValidLongitude(double longitude) { + return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; + } + } + + public class CoordinateValidationException(double latitude, double longitude) + : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { + public double Latitude { get; } + + public double Longitude { get; } + } + } } diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs index 5b4f6f80..87f9c8c7 100644 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs @@ -5,10 +5,11 @@ namespace PolylineAlgorithm.Implementation.Benchmarks; +using BenchmarkDotNet.Configs; using BenchmarkDotNet.Running; internal class Program { - static void Main(string[] _) { + static void Main(string[] args) { BenchmarkRunner .Run(); BenchmarkRunner diff --git a/src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs b/src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs index 9ffdae03..062bff12 100644 --- a/src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs +++ b/src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs @@ -10,23 +10,22 @@ namespace PolylineAlgorithm.DependencyInjection.Autofac; public static class ContainerBuilderExtensions { /// - /// Registers singleton instances of - /// , - /// and - /// into . + /// Registers singleton instances of + /// + /// and + /// into . /// /// Instance of to register polyline services into. - public static void RegisterPolylineAlgorithm(this ContainerBuilder builder) { - builder.RegisterType() - .As() + /// + /// TCoordinate is . + /// + public static void RegisterDefaultPolylineAlgorithm(this ContainerBuilder builder) { + builder.RegisterType() + .As>() .SingleInstance(); - builder.RegisterType() - .As() - .SingleInstance(); - - builder.RegisterType() - .As() + builder.RegisterType() + .As>() .SingleInstance(); } } diff --git a/src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs b/src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs index 4c7c9d47..77737c09 100644 --- a/src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs +++ b/src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs @@ -10,17 +10,19 @@ namespace PolylineAlgorithm.DependencyInjection.Microsoft; public static class ServiceCollectionExtensions { /// - /// Registers singleton instances of - /// , - /// and - /// to . + /// Adds a singleton service of the type specified in and + /// with an implementation type and + /// to the specified . /// - /// Instance of - /// Instance of - public static IServiceCollection AddPolylineAlgorithm(this IServiceCollection services) { + /// The to add the services to. + /// A reference to instance after the operation has completed.. + /// + /// TCoordinate is . + /// + public static IServiceCollection AddDefaultPolylineAlgorithm(this IServiceCollection services) { return services - .AddSingleton() - .AddSingleton() - .AddSingleton(); + .AddSingleton, DefaultPolylineEncoder>() + .AddSingleton, DefaultPolylineDecoder>(); + } } diff --git a/src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineDecoder.cs b/src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineDecoder.cs new file mode 100644 index 00000000..3cd8470c --- /dev/null +++ b/src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineDecoder.cs @@ -0,0 +1,11 @@ +namespace PolylineAlgorithm.NetTopologySuite; + +using global::NetTopologySuite.Geometries; +using PolylineAlgorithm.Abstraction; + +/// +public sealed class NetTopologyPolylineDecoder : PolylineDecoder { + protected override Point CreateCoordinate(ref readonly double latitude, ref readonly double longitude) { + return new Point(latitude, longitude); + } +} diff --git a/src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineEncoder.cs b/src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineEncoder.cs new file mode 100644 index 00000000..b253eb7d --- /dev/null +++ b/src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineEncoder.cs @@ -0,0 +1,20 @@ +namespace PolylineAlgorithm.NetTopologySuite; + +using global::NetTopologySuite.Geometries; +using PolylineAlgorithm.Abstraction; +using System; + +/// +public sealed class NetTopologyPolylineEncoder : PolylineEncoder { + protected override double GetLatitude(ref readonly Coordinate coordinate) { + ArgumentNullException.ThrowIfNull(coordinate); + + return coordinate.X; + } + + protected override double GetLongitude(ref readonly Coordinate coordinate) { + ArgumentNullException.ThrowIfNull(coordinate); + + return coordinate.Y; + } +} diff --git a/src/PolylineAlgorithm.NetTopologySuite/PolylineAlgorithm.NetTopologySuite.csproj b/src/PolylineAlgorithm.NetTopologySuite/PolylineAlgorithm.NetTopologySuite.csproj new file mode 100644 index 00000000..10122e51 --- /dev/null +++ b/src/PolylineAlgorithm.NetTopologySuite/PolylineAlgorithm.NetTopologySuite.csproj @@ -0,0 +1,27 @@ + + + + net8.0 + 13.0 + enable + enable + true + + + + All + latest + true + true + true + + + + + + + + + + + diff --git a/src/PolylineAlgorithm/Abstraction/ICoordinateValidator.cs b/src/PolylineAlgorithm/Abstraction/ICoordinateValidator.cs deleted file mode 100644 index 08752927..00000000 --- a/src/PolylineAlgorithm/Abstraction/ICoordinateValidator.cs +++ /dev/null @@ -1,18 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Abstraction; - -/// -/// Provides validation of a coordinate value. -/// -public interface ICoordinateValidator { - /// - /// Determines whether the value of a coordinate is valid. - /// - /// The coordinate value to be validated. - /// if the parameter is a valid; otherwise, . - bool IsValid((double Latitude, double Longitude) coordinate); -} \ No newline at end of file diff --git a/src/PolylineAlgorithm/Abstraction/IPolylineDecoder.cs b/src/PolylineAlgorithm/Abstraction/IPolylineDecoder.cs index 250a4aee..54352703 100644 --- a/src/PolylineAlgorithm/Abstraction/IPolylineDecoder.cs +++ b/src/PolylineAlgorithm/Abstraction/IPolylineDecoder.cs @@ -5,16 +5,16 @@ namespace PolylineAlgorithm.Abstraction; -using System.Collections.Generic; +using System.Collections.ObjectModel; /// /// Converts an encoded polyline string into a set of latitude and longitude coordinates. /// -public interface IPolylineDecoder { +public interface IPolylineDecoder { /// - /// Decodes an encoded polyline string into a set of value tuples representing latitude and longitude coordinates. + /// Decodes an encoded polyline string into a set of . /// - /// An encoded polyline string to decode. - /// A set of value tuples representing latitude and longitude coordinates. - IEnumerable<(double Latitude, double Longitude)> Decode(string polyline); + /// An encoded polyline string to decode. + /// A decoded polyline. + Span Decode(Polyline polyline); } \ No newline at end of file diff --git a/src/PolylineAlgorithm/Abstraction/IPolylineEncoder.cs b/src/PolylineAlgorithm/Abstraction/IPolylineEncoder.cs index 5ff66ac6..801a425c 100644 --- a/src/PolylineAlgorithm/Abstraction/IPolylineEncoder.cs +++ b/src/PolylineAlgorithm/Abstraction/IPolylineEncoder.cs @@ -10,11 +10,11 @@ namespace PolylineAlgorithm.Abstraction; /// /// Converts a set of latitude and longitude coordinates into an encoded polyline string. /// -public interface IPolylineEncoder { +public interface IPolylineEncoder { /// /// Encodes a set of value tuples representing latitude and longitude coordinates into an encoded polyline string. /// /// A set of value tuples representing latitude and longitude coordinates. /// An encoded polyline string representing a set of latitude and longitude coordinates. - string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates); + Polyline Encode(IEnumerable coordinates); } \ No newline at end of file diff --git a/src/PolylineAlgorithm/Abstraction/PolylineDecoder.cs b/src/PolylineAlgorithm/Abstraction/PolylineDecoder.cs new file mode 100644 index 00000000..0423983d --- /dev/null +++ b/src/PolylineAlgorithm/Abstraction/PolylineDecoder.cs @@ -0,0 +1,84 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Abstraction; + +using PolylineAlgorithm.Internal; + +/// +/// A coordinate validator. +public abstract class PolylineDecoder : IPolylineDecoder { + + /// + /// Thrown when argument is null -or- empty. + /// Thrown when is not in correct format. + public Span Decode(Polyline polyline) { + // Checking null and at least one character + if (polyline.IsEmpty) { + throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullEmptyOrWhitespace, nameof(polyline)); + } + + // Initialize local variables + int position = 0; + int roundedLatitude = 0; + int roundedLongitude = 0; + int count = (int)Math.Ceiling(polyline.Length / 8d); + Span coordinates = new TCoordinate[count]; + int index = 0; + + // Looping through encoded polyline char array + while (position < polyline.Length) { + // Attempting to calculate next latitude value. If failed exception is thrown. + if (!TryDecodeNext(ref polyline, ref position, ref roundedLatitude)) { + throw new InvalidOperationException(ExceptionMessageResource.PolylineStringIsMalformed); + } + + // Attempting to calculate next longitude value. If failed exception is thrown. + if (!TryDecodeNext(ref polyline, ref position, ref roundedLongitude)) { + throw new InvalidOperationException(ExceptionMessageResource.PolylineStringIsMalformed); + } + + double latitude = Precise(ref roundedLatitude); + double longitude = Precise(ref roundedLongitude); + + coordinates[index] = CreateCoordinate(in latitude, in longitude); + index++; + } + + return coordinates[..index]; + } + + static bool TryDecodeNext(ref Polyline polyline, ref int position, ref int value) { + // Initialize local variables + int chunk; + int sum = 0; + int shifter = 0; + + do { + chunk = polyline[position++] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + } while (chunk >= Constants.ASCII.Space && position < polyline.Length); + + if (position >= polyline.Length && chunk >= Constants.ASCII.Space) + return false; + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + + return true; + } + + private static double Precise(ref int value) { + return Convert.ToDouble(value) / Constants.Precision; + } + + /// + /// Creates an instance of + /// + /// A latitude value + /// A longitude value + /// An instance of + protected abstract TCoordinate CreateCoordinate(ref readonly double latitude, ref readonly double longitude); +} \ No newline at end of file diff --git a/src/PolylineAlgorithm/Abstraction/PolylineEncoder.cs b/src/PolylineAlgorithm/Abstraction/PolylineEncoder.cs new file mode 100644 index 00000000..548b06e2 --- /dev/null +++ b/src/PolylineAlgorithm/Abstraction/PolylineEncoder.cs @@ -0,0 +1,90 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Abstraction; + +using PolylineAlgorithm.Internal; +using System; +using System.Collections.Generic; +using System.Linq; + +/// +/// Performs polyline algorithm decoding and encoding +/// +public abstract class PolylineEncoder() : IPolylineEncoder { + //public ICoordinateValidator Validator { get; } = validator ?? throw new ArgumentNullException(nameof(validator)); + + /// + /// Encodes coordinates to polyline representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null + /// If coordinates parameter is empty + /// If one or more coordinate is out of valid range + public Polyline Encode(IEnumerable coordinates) { + if (coordinates is null) { + throw new ArgumentNullException(nameof(coordinates)); + } + + Span temp = coordinates.ToArray(); + + if (temp.IsEmpty) { + throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeEmptyEnumerable, nameof(coordinates)); + } + + // Initializing local variables + int index = 0; + Memory buffer = new char[GetSafeBufferSize(temp.Length)]; + int initialLatitude = 0; + int initialLongitude = 0; + + // Looping over coordinates and building encoded result + foreach (var coordinate in temp) { + int latitude = Round(GetLatitude(in coordinate)); + int longitude = Round(GetLongitude(in coordinate)); + + WriteNext(ref buffer, ref index, ref latitude, ref initialLatitude); + WriteNext(ref buffer, ref index, ref longitude, ref initialLongitude); + } + + return new Polyline(buffer[..index]); + } + + // Each coordinate consist of two values, each one is 4 or 5 chars long + // We use 12 = [2 coordinate values * 6 characters per each] to create safe buffer size + static int GetSafeBufferSize(int count) => count * 12; + + protected abstract double GetLatitude(ref readonly TCoordinate coordinate); + + protected abstract double GetLongitude(ref readonly TCoordinate coordinate); + + static int Round(double value) { + return (int)Math.Round(value * Constants.Precision); + } + + static void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { + int value = current - previous; + int shifted = value << 1; + + if (value < 0) { + shifted = ~shifted; + } + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) { + buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + rem >>= Constants.ShiftLength; + index++; + } + + buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); + + index++; + + previous = current; + } +} diff --git a/src/PolylineAlgorithm/Coordinate.cs b/src/PolylineAlgorithm/Coordinate.cs new file mode 100644 index 00000000..d9b04e18 --- /dev/null +++ b/src/PolylineAlgorithm/Coordinate.cs @@ -0,0 +1,89 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; + +using System; + +public readonly struct Coordinate : IEquatable { + private static CoordinateRange ValidLatitude { get; } = new CoordinateRange(-90d, 90d); + private static CoordinateRange ValidLongitude { get; } = new CoordinateRange(-180d, 180d); + + public static Coordinate Create(double latitude, double longitude) { + ValidateCoordinate(ref latitude, ref longitude, out var exceptions); + + if (exceptions.Count == 0) { + return new Coordinate(latitude, longitude); + } else if (exceptions.Count == 1) { + throw exceptions[0]; + } else { + throw new AggregateException(exceptions); + } + + static void ValidateCoordinate(ref double latitude, ref double longitude, out List exceptions) { + exceptions = new List(2); + + if (!ValidLatitude.IsInRange(latitude)) { + exceptions.Add(new ArgumentException()); + } + + if (!ValidLongitude.IsInRange(longitude)) { + exceptions.Add(new ArgumentException()); + } + } + } + + /// + /// Initialized default instance of . + /// + /// Use to initialize non-default instance. + public Coordinate() { + Latitude = 0d; + Longitude = 0d; + } + + private Coordinate(double latitude, double longitude) { + Latitude = latitude; + Longitude = longitude; + } + + public double Latitude { get; } + public double Longitude { get; } + + public bool IsDefault + => Latitude == default + && Longitude == default; + + public override bool Equals(object? obj) + => obj is Coordinate coordinate && Equals(coordinate); + + public bool Equals(Coordinate other) + => Latitude == other.Latitude + && Longitude == other.Longitude; + + public override int GetHashCode() + => HashCode.Combine(Latitude, Longitude); + + public static bool operator ==(Coordinate left, Coordinate right) + => left.Equals(right); + + public static bool operator !=(Coordinate left, Coordinate right) + => !(left == right); + + private readonly struct CoordinateRange { + public CoordinateRange(double min, double max) { + if (min >= max) { + throw new ArgumentException(); + } + + Min = min; + Max = max; + } + public double Min { get; } + public double Max { get; } + + public bool IsInRange(double value) => value >= Min && value <= Max; + } +} diff --git a/src/PolylineAlgorithm/CoordinateValidationException.cs b/src/PolylineAlgorithm/CoordinateValidationException.cs deleted file mode 100644 index d398899b..00000000 --- a/src/PolylineAlgorithm/CoordinateValidationException.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm; - -using System; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; - -/// -/// The exception that is thrown when coordinate is not valid. -/// -/// An invalid coordinate that caused the exception. -[DebuggerDisplay($"{{{nameof(GetFormattedMessage)}(),nq}}")] -[SuppressMessage("Design", "CA1032:Implement standard exception constructors", Justification = "There is no reason to have standard constructors.")] -public sealed class CoordinateValidationException((double Latitude, double Longitude) coordinate) - : Exception(GetFormattedMessage(coordinate)) { - - /// - /// An invalid coordinate that caused the exception. - /// - public (double Latitude, double Longitude) Coordinate { get; } - - /// - /// Returns a formatted exception message. - /// - /// An invalid coordinate that caused the exception. - /// A formatted exception message. - private static string GetFormattedMessage((double Latitude, double Longitude) coordinate) - => string.Format( - ExceptionMessageResource.CoordinateValidationExceptionCoordinateIsOutOfRangeErrorMessageFormat, - coordinate.Latitude, - coordinate.Longitude - ); -} diff --git a/src/PolylineAlgorithm/CoordinateValidator.cs b/src/PolylineAlgorithm/CoordinateValidator.cs deleted file mode 100644 index 3f47c3e5..00000000 --- a/src/PolylineAlgorithm/CoordinateValidator.cs +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm; - -using PolylineAlgorithm.Abstraction; -using PolylineAlgorithm.Internal; - -/// -public sealed class CoordinateValidator : ICoordinateValidator { - public bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(ref coordinate.Latitude) && IsValidLongitude(ref coordinate.Longitude); - } - - /// - /// Determines whether the value of a latitude is valid. - /// - /// The latitude to be validated. - /// if the parameter is a valid; otherwise, . - private static bool IsValidLatitude(ref readonly double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - /// - /// Determines whether the value of a latitude is valid. - /// - /// The longitude to be validated. - /// if the parameter is a valid; otherwise, . - private static bool IsValidLongitude(ref readonly double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } -} diff --git a/src/PolylineAlgorithm/DefaultPolylineDecoder.cs b/src/PolylineAlgorithm/DefaultPolylineDecoder.cs new file mode 100644 index 00000000..ffecf21e --- /dev/null +++ b/src/PolylineAlgorithm/DefaultPolylineDecoder.cs @@ -0,0 +1,15 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; + +using PolylineAlgorithm.Abstraction; + +/// +public sealed class DefaultPolylineDecoder : PolylineDecoder { + protected override Coordinate CreateCoordinate(ref readonly double latitude, ref readonly double longitude) { + return Coordinate.Create(latitude, longitude); + } +} \ No newline at end of file diff --git a/src/PolylineAlgorithm/DefaultPolylineEncoder.cs b/src/PolylineAlgorithm/DefaultPolylineEncoder.cs new file mode 100644 index 00000000..28257a65 --- /dev/null +++ b/src/PolylineAlgorithm/DefaultPolylineEncoder.cs @@ -0,0 +1,21 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; + +using PolylineAlgorithm.Abstraction; + +/// +/// Performs polyline algorithm decoding and encoding +/// +public sealed class DefaultPolylineEncoder() : PolylineEncoder { + protected override double GetLatitude(ref readonly Coordinate coordinate) { + return coordinate.Latitude; + } + + protected override double GetLongitude(ref readonly Coordinate coordinate) { + return coordinate.Longitude; + } +} diff --git a/src/PolylineAlgorithm/Internal/Constants.cs b/src/PolylineAlgorithm/Internal/Constants.cs index f8babb76..c487eb7b 100644 --- a/src/PolylineAlgorithm/Internal/Constants.cs +++ b/src/PolylineAlgorithm/Internal/Constants.cs @@ -38,29 +38,29 @@ internal static class ASCII { public const int UnitSeparator = 31; } - /// - /// Defines coordinates constant values - /// - internal static class Coordinate { - /// - /// Defines the maximum value for latitude - /// - public const int MaxLatitude = 90; + ///// + ///// Defines coordinates constant values + ///// + //internal static class Coordinate { + // /// + // /// Defines the maximum value for latitude + // /// + // public const int MaxLatitude = 90; - /// - /// Defines the maximum value for longitude - /// - public const int MaxLongitude = 180; + // /// + // /// Defines the maximum value for longitude + // /// + // public const int MaxLongitude = 180; - /// - /// Defines the maximum value for latitude - /// - public const int MinLatitude = -MaxLatitude; + // /// + // /// Defines the maximum value for latitude + // /// + // public const int MinLatitude = -MaxLatitude; - /// - /// Defines the maximum value for longitude - /// - public const int MinLongitude = -MaxLongitude; - } + // /// + // /// Defines the maximum value for longitude + // /// + // public const int MinLongitude = -MaxLongitude; + //} } } diff --git a/src/PolylineAlgorithm/ExceptionMessageResource.Designer.cs b/src/PolylineAlgorithm/Internal/ExceptionMessageResource.Designer.cs similarity index 90% rename from src/PolylineAlgorithm/ExceptionMessageResource.Designer.cs rename to src/PolylineAlgorithm/Internal/ExceptionMessageResource.Designer.cs index 187e57ee..cb483916 100644 --- a/src/PolylineAlgorithm/ExceptionMessageResource.Designer.cs +++ b/src/PolylineAlgorithm/Internal/ExceptionMessageResource.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace PolylineAlgorithm { +namespace PolylineAlgorithm.Internal { using System; @@ -39,7 +39,7 @@ internal ExceptionMessageResource() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PolylineAlgorithm.ExceptionMessageResource", typeof(ExceptionMessageResource).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PolylineAlgorithm.Internal.ExceptionMessageResource", typeof(ExceptionMessageResource).Assembly); resourceMan = temp; } return resourceMan; @@ -79,11 +79,11 @@ internal static string ArgumentCannotBeEmptyEnumerable { } /// - /// Looks up a localized string similar to Argument cannot be null -or- empty char array.. + /// Looks up a localized string similar to Argument cannot be null -or- empty -or- whitespace string.. /// - internal static string ArgumentCannotBeNullOrEmpty { + internal static string ArgumentCannotBeNullEmptyOrWhitespace { get { - return ResourceManager.GetString("ArgumentCannotBeNullOrEmpty", resourceCulture); + return ResourceManager.GetString("ArgumentCannotBeNullEmptyOrWhitespace", resourceCulture); } } @@ -99,9 +99,9 @@ internal static string CoordinateValidationExceptionCoordinateIsOutOfRangeErrorM /// /// Looks up a localized string similar to Polyline is malformed.. /// - internal static string PolylineCharArrayIsMalformed { + internal static string PolylineStringIsMalformed { get { - return ResourceManager.GetString("PolylineCharArrayIsMalformed", resourceCulture); + return ResourceManager.GetString("PolylineStringIsMalformed", resourceCulture); } } } diff --git a/src/PolylineAlgorithm/ExceptionMessageResource.resx b/src/PolylineAlgorithm/Internal/ExceptionMessageResource.resx similarity index 96% rename from src/PolylineAlgorithm/ExceptionMessageResource.resx rename to src/PolylineAlgorithm/Internal/ExceptionMessageResource.resx index 8eabe752..4ed158c8 100644 --- a/src/PolylineAlgorithm/ExceptionMessageResource.resx +++ b/src/PolylineAlgorithm/Internal/ExceptionMessageResource.resx @@ -120,8 +120,8 @@ One or more coordinates are invalid. Check InnerExceptions property for details. - - Argument cannot be null -or- empty char array. + + Argument cannot be null -or- empty -or- whitespace string. Argument cannot be an empty enumerable. @@ -129,7 +129,7 @@ Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180. - + Polyline is malformed. \ No newline at end of file diff --git a/src/PolylineAlgorithm/Polyline.cs b/src/PolylineAlgorithm/Polyline.cs new file mode 100644 index 00000000..04749496 --- /dev/null +++ b/src/PolylineAlgorithm/Polyline.cs @@ -0,0 +1,61 @@ +namespace PolylineAlgorithm; + +using System; + +public readonly struct Polyline : IEquatable { + public Polyline() { + Value = Memory.Empty; + } + + public Polyline(string polyline) + : this(polyline.AsMemory()) { + if (string.IsNullOrWhiteSpace(polyline)) { + throw new ArgumentException($"'{nameof(polyline)}' cannot be null or whitespace.", nameof(polyline)); + } + } + + public Polyline(char[] polyline) + : this(polyline.AsMemory()) { + if (polyline is null) { + throw new ArgumentNullException(nameof(polyline)); + } + } + + internal Polyline(ReadOnlyMemory polyline) { + Value = polyline; + } + + public ReadOnlyMemory Value { get; } + + public bool IsEmpty => Value.Length == 0; + + public int Length => Value.Length; + + public char this[int i] { + get => Value.Span[i]; + } + + public override bool Equals(object? obj) { + return obj is Polyline polyline && Equals(polyline); + } + + public bool Equals(Polyline other) { + return Value.Span == other.Value.Span; + } + + public override int GetHashCode() { + return HashCode.Combine(Value); + } + + public static bool operator ==(Polyline left, Polyline right) { + return left.Equals(right); + } + + public static bool operator !=(Polyline left, Polyline right) { + return !(left == right); + } + + public override string ToString() { + return Value.ToString(); + } +} diff --git a/src/PolylineAlgorithm/PolylineAlgorithm.csproj b/src/PolylineAlgorithm/PolylineAlgorithm.csproj index 6314df9f..e2c54c2b 100644 --- a/src/PolylineAlgorithm/PolylineAlgorithm.csproj +++ b/src/PolylineAlgorithm/PolylineAlgorithm.csproj @@ -18,7 +18,7 @@ - + True True ExceptionMessageResource.resx @@ -26,7 +26,7 @@ - + ResXFileCodeGenerator ExceptionMessageResource.Designer.cs diff --git a/src/PolylineAlgorithm/PolylineDecoder.cs b/src/PolylineAlgorithm/PolylineDecoder.cs deleted file mode 100644 index 607d0da0..00000000 --- a/src/PolylineAlgorithm/PolylineDecoder.cs +++ /dev/null @@ -1,83 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm; - -using PolylineAlgorithm.Abstraction; -using PolylineAlgorithm.Internal; - -/// -/// A coordinate validator. -public sealed class PolylineDecoder(ICoordinateValidator validator) : IPolylineDecoder { - public ICoordinateValidator Validator { get; } = validator ?? throw new ArgumentNullException(nameof(validator)); - - /// - /// Thrown when argument is null -or- empty. - /// Thrown when is not in correct format. - public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - // Checking null and at least one character - if (polyline == null || polyline.Length == 0) { - throw new ArgumentException(string.Empty, nameof(polyline)); - } - - // Initialize local variables - int index = 0; - int latitude = 0; - int longitude = 0; - - // Looping through encoded polyline char array - while (index < polyline.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown. - if (!TryDecodeNext(polyline, ref index, ref latitude)) { - throw new InvalidOperationException(string.Empty); - } - - // Attempting to calculate next longitude value. If failed exception is thrown. - if (!TryDecodeNext(polyline, ref index, ref longitude)) { - throw new InvalidOperationException(string.Empty); - } - - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - - // Validating decoded coordinate. If not valid exception is thrown. - if (!Validator.IsValid(coordinate)) { - throw new InvalidOperationException(string.Empty); - } - - yield return coordinate; - } - } - - /// - /// - /// - /// - /// - /// - /// - private static bool TryDecodeNext(string polyline, ref int index, ref int value) { - // Initialize local variables - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - private static double GetCoordinate(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } -} \ No newline at end of file diff --git a/src/PolylineAlgorithm/PolylineEncoder.cs b/src/PolylineAlgorithm/PolylineEncoder.cs deleted file mode 100644 index 70d15b9b..00000000 --- a/src/PolylineAlgorithm/PolylineEncoder.cs +++ /dev/null @@ -1,103 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm; - -using PolylineAlgorithm.Abstraction; -using PolylineAlgorithm.Internal; -using System; -using System.Collections.Generic; -using System.Linq; - -/// -/// Performs polyline algorithm decoding and encoding -/// -public sealed class PolylineEncoder(ICoordinateValidator validator) : IPolylineEncoder { - public ICoordinateValidator Validator { get; } = validator ?? throw new ArgumentNullException(nameof(validator)); - - /// - /// Encodes coordinates to polyline representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null - /// If coordinates parameter is empty - /// If one or more coordinate is out of valid range - public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates is null) { - throw new ArgumentNullException(nameof(coordinates)); - } - - if (!coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeEmptyEnumerable, nameof(coordinates)); - } - - int count = coordinates.Count(); - ICollection exceptions = new List(count); - - // Validate collection of coordinates - if (!TryValidate(coordinates, ref exceptions)) { - throw new AggregateException(ExceptionMessageResource.AggregateExceptionCoordinatesAreInvalidErrorMessage, exceptions); - } - - // Initializing local variables - int index = 0; - Memory buffer = new char[GetSafeBufferSize(count)]; - int previousLatitude = 0; - int previousLongitude = 0; - - // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(Latitude); - int longitude = Round(Longitude); - - WriteNext(ref buffer, ref index, ref latitude, ref previousLatitude); - WriteNext(ref buffer, ref index, ref longitude, ref previousLongitude); - } - - return buffer[..index].ToString(); - - // Each coordinate consist of two values, each one is 4 or 5 chars long - // We use 12 = [2 * 6] to create safe buffer size - static int GetSafeBufferSize(int count) => count * 12; - } - - private bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { - foreach (var item in collection) { - if (!Validator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item)); - } - } - - return exceptions.Count == 0; - } - - private static int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - private static void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { - int value = current - previous; - int shifted = value << 1; - - if (value < 0) { - shifted = ~shifted; - } - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - rem >>= Constants.ShiftLength; - index++; - } - - buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); - - index++; - - previous = current; - } -} diff --git a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs index af984005..95088cba 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs @@ -19,25 +19,12 @@ public static void ClassInitialize(TestContext context) { var builder = new ContainerBuilder(); builder - .RegisterPolylineAlgorithm(); + .RegisterDefaultPolylineAlgorithm(); Container = builder .Build(); } - [TestMethod] - public void Resolve_CoordinateValidator_Test() { - // Arrange - var container = Container; - - // Act - var validator = container - .Resolve(); - - // Assert - Assert.IsInstanceOfType(validator); - } - [TestMethod] public void Resolve_PolylineEncoder_Test() { // Arrange @@ -45,10 +32,10 @@ public void Resolve_PolylineEncoder_Test() { // Act var encoder = container - .Resolve(); + .Resolve>(); // Assert - Assert.IsInstanceOfType(encoder); + Assert.IsInstanceOfType>(encoder); } [TestMethod] @@ -58,9 +45,9 @@ public void Resolve_PolylineDecoder_Test() { // Act var decoder = container - .Resolve(); + .Resolve>(); // Assert - Assert.IsInstanceOfType(decoder); + Assert.IsInstanceOfType>(decoder); } } \ No newline at end of file diff --git a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs index 4969faa0..bcfff761 100644 --- a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs +++ b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs @@ -3,28 +3,14 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.DependencyInjection.Tests; +namespace PolylineAlgorithm.DependencyInjection.Microsoft.Tests; using PolylineAlgorithm.Abstraction; using PolylineAlgorithm.DependencyInjection.Microsoft; [TestClass] public class ServiceCollectionExtensionsTests { - private static IServiceCollection Services { get; } = new ServiceCollection().AddPolylineAlgorithm(); - - [TestMethod] - public void Resolve_CoordinateValidator_Test() { - // Arrange - var provider = Services - .BuildServiceProvider(); - - // Act - var validator = provider - .GetRequiredService(); - - // Assert - Assert.IsInstanceOfType(validator); - } + private static IServiceCollection Services { get; } = new ServiceCollection().AddDefaultPolylineAlgorithm(); [TestMethod] public void Resolve_PolylineEncoder_Test() { @@ -34,10 +20,10 @@ public void Resolve_PolylineEncoder_Test() { // Act var encoder = provider - .GetRequiredService(); + .GetRequiredService>(); // Assert - Assert.IsInstanceOfType(encoder); + Assert.IsInstanceOfType>(encoder); } [TestMethod] @@ -48,9 +34,9 @@ public void Resolve_PolylineDecoder_Test() { // Act var decoder = provider - .GetRequiredService(); + .GetRequiredService>(); // Assert - Assert.IsInstanceOfType(decoder); + Assert.IsInstanceOfType>(decoder); } } \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs b/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs deleted file mode 100644 index aa59c4f7..00000000 --- a/tests/PolylineAlgorithm.Tests/CoordinateValidatorTest.cs +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Tests; - -using PolylineAlgorithm; - -/// -/// Defines the -/// -[TestClass] -[TestCategory(nameof(CoordinateValidator))] -public class CoordinateValidatorTestCoordinate { - private static CoordinateValidator Validator { get; } = new CoordinateValidator(); - - #region Methods - - /// - /// The IsValid_InvalidInput - /// - [TestMethod] - public void IsValid_InvalidInput_IsFalse() { - // Act - var invalidCoordinateCollection = Defaults.Coordinate.Invalid; - - foreach (var item in invalidCoordinateCollection) { - // Arrange - var result = Validator.IsValid(item); - - // Assert - Assert.IsFalse(result); - } - } - - /// - /// The IsValid_ValidInput - /// - [TestMethod] - public void IsValid_ValidInput_IsTrue() { - // Act - var validCoordinateCollection = Defaults.Coordinate.Valid; - - foreach (var item in validCoordinateCollection) { - // Arrange - var result = Validator.IsValid(item); - - // Assert - Assert.IsTrue(result); - } - } - - #endregion -} diff --git a/tests/PolylineAlgorithm.Tests/Defaults.cs b/tests/PolylineAlgorithm.Tests/Defaults.cs index f2229688..d9594d5b 100644 --- a/tests/PolylineAlgorithm.Tests/Defaults.cs +++ b/tests/PolylineAlgorithm.Tests/Defaults.cs @@ -15,30 +15,30 @@ public static class Defaults { /// /// Defines default decoded values and objects udÅ›ed for testing purposes /// - public static class Coordinate { + public static class Coordinates { /// /// Defines empty range of coordinates. Equals to decoded /// - public static readonly IEnumerable<(double Latitude, double Longitude)> Empty = []; + public static readonly IEnumerable Empty = []; /// /// Defines range of invalid coordinates. Equals to decoded /// - public static readonly IEnumerable<(double Latitude, double Longitude)> Invalid = [ - (149.47383, 259.06250), - (-158.37407, 225.31250), - (152.99363, -220.93750), - (-144.49024, -274.37500) + public static readonly IEnumerable Invalid = [ + Coordinate.Create(149.47383, 259.06250), + Coordinate.Create(-158.37407, 225.31250), + Coordinate.Create(152.99363, -220.93750), + Coordinate.Create(-144.49024, -274.37500) ]; /// /// Defines range of valid coordinates. Equals to decoded /// - public static readonly IEnumerable<(double Latitude, double Longitude)> Valid = [ - (49.47383, 59.06250), - (-58.37407, 25.31250), - (52.99363, -120.93750), - (-44.49024, -174.37500) + public static readonly IEnumerable Valid = [ + Coordinate.Create(49.47383, 59.06250), + Coordinate.Create(-58.37407, 25.31250), + Coordinate.Create(52.99363, -120.93750), + Coordinate.Create(-44.49024, -174.37500) ]; } @@ -47,17 +47,17 @@ public static class Coordinate { /// public static class Polyline { /// - /// Defines empty string of polyline encoded coordinates. Equals to encoded + /// Defines empty string of polyline encoded coordinates. Equals to encoded /// - public static readonly string Empty = String.Empty; + public static readonly string Empty = string.Empty; /// - /// Defines polyline encoded range of invalid coordinates. Equals to encoded + /// Defines polyline encoded range of invalid coordinates. Equals to encoded /// public static readonly string Invalid = "mnc~Qsm_ja@"; /// - /// Defines polyline encoded range of valid coordinates. Equals to encoded + /// Defines polyline encoded range of valid coordinates. Equals to encoded /// public static readonly string Valid = "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; } diff --git a/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs b/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs index 4d0b8429..1ffd70da 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs +++ b/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs @@ -5,13 +5,15 @@ namespace PolylineAlgorithm.Tests; +using PolylineAlgorithm; + /// /// Defines the /// [TestClass] -[TestCategory(nameof(PolylineDecoder))] +[TestCategory(nameof(DefaultPolylineDecoder))] public class PolylineDecoderTest { - private static PolylineDecoder Decoder { get; } = new PolylineDecoder(new CoordinateValidator()); + private static DefaultPolylineDecoder Decoder { get; } = new DefaultPolylineDecoder(); /// /// Method is testing method. Empty [] is passed as parameter. @@ -20,7 +22,7 @@ public class PolylineDecoderTest { [TestMethod] public void Decode_EmptyInput_ThrowsException() { // Arrange - var emptyPolylineCharArray = Defaults.Polyline.Empty; + var emptyPolylineCharArray = new Polyline(Defaults.Polyline.Empty); // Act void DecodeEmptyPolylineCharArray() { @@ -31,24 +33,6 @@ void DecodeEmptyPolylineCharArray() { Assert.ThrowsException(DecodeEmptyPolylineCharArray); } - /// - /// Method is testing method. [] with invalid coordinates is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Decode_InvalidInput_ThrowsException() { - // Arrange - var invalidPolylineCharrArray = Defaults.Polyline.Invalid; - - // Act - void DecodeInvalidPolylineCharArray() { - Decoder.Decode(invalidPolylineCharrArray).ToArray(); - } - - // Assert - Assert.ThrowsException(DecodeInvalidPolylineCharArray); - } - /// /// Method is testing method. [] with valid coordinates is passed as parameter. /// Expected result is . @@ -56,12 +40,12 @@ void DecodeInvalidPolylineCharArray() { [TestMethod] public void Decode_ValidInput_AreEquivalent() { // Arrange - var validPolylineCharArray = Defaults.Polyline.Valid; + var validPolylineCharArray = new Polyline(Defaults.Polyline.Valid); // Act var result = Decoder.Decode(validPolylineCharArray); // Assert - CollectionAssert.AreEquivalent(Defaults.Coordinate.Valid.ToList(), result.ToList()); + CollectionAssert.AreEquivalent(Defaults.Coordinates.Valid.ToArray(), result.ToArray()); } } diff --git a/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs b/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs index cad05d5e..867a548b 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs +++ b/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs @@ -4,14 +4,13 @@ // namespace PolylineAlgorithm.Tests; - /// /// Defines the /// [TestClass] -[TestCategory(nameof(PolylineEncoder))] +[TestCategory(nameof(DefaultPolylineEncoder))] public class PolylineEncoderTest { - private static PolylineEncoder Encoder { get; } = new PolylineEncoder(new CoordinateValidator()); + private static DefaultPolylineEncoder Encoder { get; } = new DefaultPolylineEncoder(); /// /// Method is testing method. Empty is passed as parameter. @@ -20,7 +19,7 @@ public class PolylineEncoderTest { [TestMethod] public void Encode_EmptyInput_ThrowsException() { // Arrange - var emptyCoordinates = Defaults.Coordinate.Empty; + var emptyCoordinates = Defaults.Coordinates.Empty; // Act void EncodeEmptyCoordinates() { @@ -31,23 +30,6 @@ void EncodeEmptyCoordinates() { Assert.ThrowsException(() => EncodeEmptyCoordinates()); } - /// - /// The Encode_InvalidInput - /// - [TestMethod] - public void Encode_InvalidInput_ThrowsException() { - // Arrange - var invalidCoordinates = Defaults.Coordinate.Invalid; - - // Act - void EncodeInvalidCoordinates() { - Encoder.Encode(invalidCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeInvalidCoordinates()); - } - /// /// Method is testing method. is passed as parameter. /// Expected result is . @@ -55,7 +37,7 @@ void EncodeInvalidCoordinates() { [TestMethod] public void Encode_NullInput_ThrowsException() { // Arrange - var nullCoordinates = (IEnumerable<(double, double)>)null!; + var nullCoordinates = (IEnumerable)null!; // Act void EncodeNullCoordinates() { @@ -72,12 +54,12 @@ void EncodeNullCoordinates() { [TestMethod] public void Encode_ValidInput_AreEqual() { // Arrange - var validCoordinates = Defaults.Coordinate.Valid; + var validCoordinates = Defaults.Coordinates.Valid; // Act var result = Encoder.Encode(validCoordinates); // Assert - Assert.AreEqual(Defaults.Polyline.Valid, result); + Assert.AreEqual(new Polyline(Defaults.Polyline.Valid), result); } } From 7c0823cf28924ccb0620900d5c3f6668725a4180 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Tue, 28 Jan 2025 23:50:54 +0100 Subject: [PATCH 038/352] improvements, cleanup, etc --- PolylineAlgorithm.sln | 42 - .../PolylineAlgorithm.Benchmarks.csproj | 3 + .../PolylineBenchmark.cs | 56 +- .../Constants.cs | 78 -- ...Algorithm.Implementation.Benchmarks.csproj | 29 - .../PolylineDecoderBenchmark.cs.cs | 598 ------------- .../PolylineEncoderBenchmark.cs | 819 ------------------ .../Program.cs | 18 - .../ContainerBuilderExtensions.cs | 31 - ...gorithm.DependencyInjection.Autofac.csproj | 27 - ...rithm.DependencyInjection.Microsoft.csproj | 27 - .../ServiceCollectionExtensions.cs | 28 - .../NetTopologyPolylineDecoder.cs | 11 - .../NetTopologyPolylineEncoder.cs | 20 - .../PolylineAlgorithm.NetTopologySuite.csproj | 27 - .../Abstraction/IPolylineDecoder.cs | 20 - .../Abstraction/IPolylineEncoder.cs | 20 - .../Abstraction/PolylineDecoder.cs | 84 -- .../Abstraction/PolylineEncoder.cs | 90 -- src/PolylineAlgorithm/Coordinate.cs | 79 +- src/PolylineAlgorithm/CoordinateRange.cs | 46 + src/PolylineAlgorithm/CoordinateValidator.cs | 11 + .../DefaultPolylineDecoder.cs | 15 - .../DefaultPolylineEncoder.cs | 21 - .../Internal/PolylineReader.cs | 83 ++ .../Internal/PolylineWriter.cs | 77 ++ src/PolylineAlgorithm/Polyline.cs | 61 -- src/PolylineAlgorithm/PolylineDecoder.cs | 38 + src/PolylineAlgorithm/PolylineEncoder.cs | 52 ++ .../ContainerBuilderExtensionsTests.cs | 53 -- .../GlobalSuppressions.cs | 8 - .../GlobalUsings.cs | 7 - ...m.DependencyInjection.Autofac.Tests.csproj | 42 - .../Properties/AssemblyInfo.cs | 6 - .../GlobalSuppressions.cs | 8 - .../GlobalUsings.cs | 7 - ...DependencyInjection.Microsoft.Tests.csproj | 42 - .../Properties/AssemblyInfo.cs | 6 - .../ServiceCollectionExtensionsTests.cs | 42 - tests/PolylineAlgorithm.Tests/Defaults.cs | 20 +- .../PolylineDecoderTest.cs | 22 +- .../PolylineEncoderTest.cs | 7 +- 42 files changed, 402 insertions(+), 2379 deletions(-) delete mode 100644 benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs delete mode 100644 benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj delete mode 100644 benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs delete mode 100644 benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs delete mode 100644 benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs delete mode 100644 src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs delete mode 100644 src/PolylineAlgorithm.DependencyInjection.Autofac/PolylineAlgorithm.DependencyInjection.Autofac.csproj delete mode 100644 src/PolylineAlgorithm.DependencyInjection.Microsoft/PolylineAlgorithm.DependencyInjection.Microsoft.csproj delete mode 100644 src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs delete mode 100644 src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineDecoder.cs delete mode 100644 src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineEncoder.cs delete mode 100644 src/PolylineAlgorithm.NetTopologySuite/PolylineAlgorithm.NetTopologySuite.csproj delete mode 100644 src/PolylineAlgorithm/Abstraction/IPolylineDecoder.cs delete mode 100644 src/PolylineAlgorithm/Abstraction/IPolylineEncoder.cs delete mode 100644 src/PolylineAlgorithm/Abstraction/PolylineDecoder.cs delete mode 100644 src/PolylineAlgorithm/Abstraction/PolylineEncoder.cs create mode 100644 src/PolylineAlgorithm/CoordinateRange.cs create mode 100644 src/PolylineAlgorithm/CoordinateValidator.cs delete mode 100644 src/PolylineAlgorithm/DefaultPolylineDecoder.cs delete mode 100644 src/PolylineAlgorithm/DefaultPolylineEncoder.cs create mode 100644 src/PolylineAlgorithm/Internal/PolylineReader.cs create mode 100644 src/PolylineAlgorithm/Internal/PolylineWriter.cs delete mode 100644 src/PolylineAlgorithm/Polyline.cs create mode 100644 src/PolylineAlgorithm/PolylineDecoder.cs create mode 100644 src/PolylineAlgorithm/PolylineEncoder.cs delete mode 100644 tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs delete mode 100644 tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalSuppressions.cs delete mode 100644 tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalUsings.cs delete mode 100644 tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests.csproj delete mode 100644 tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/Properties/AssemblyInfo.cs delete mode 100644 tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalSuppressions.cs delete mode 100644 tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalUsings.cs delete mode 100644 tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests.csproj delete mode 100644 tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/Properties/AssemblyInfo.cs delete mode 100644 tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs diff --git a/PolylineAlgorithm.sln b/PolylineAlgorithm.sln index 77423ead..5d7b02ac 100644 --- a/PolylineAlgorithm.sln +++ b/PolylineAlgorithm.sln @@ -21,18 +21,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolylineAlgorithm.Benchmarks", "benchmarks\PolylineAlgorithm.Benchmarks\PolylineAlgorithm.Benchmarks.csproj", "{9C7CBAD5-415B-4589-86E1-01C849F9C56C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolylineAlgorithm.Implementation.Benchmarks", "benchmarks\PolylineAlgorithm.Implementation.Benchmarks\PolylineAlgorithm.Implementation.Benchmarks.csproj", "{D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolylineAlgorithm.DependencyInjection.Microsoft.Tests", "tests\PolylineAlgorithm.DependencyInjection.Microsoft.Tests\PolylineAlgorithm.DependencyInjection.Microsoft.Tests.csproj", "{B4FD710A-E5B8-4467-8D0B-037A28132047}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolylineAlgorithm.DependencyInjection.Autofac.Tests", "tests\PolylineAlgorithm.DependencyInjection.Autofac.Tests\PolylineAlgorithm.DependencyInjection.Autofac.Tests.csproj", "{F9CFF4B1-C9AB-4F94-ADF4-B29925E1187E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolylineAlgorithm.DependencyInjection.Autofac", "src\PolylineAlgorithm.DependencyInjection.Autofac\PolylineAlgorithm.DependencyInjection.Autofac.csproj", "{9C1088DA-DBF7-4374-9775-C7613CCA98D8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolylineAlgorithm.DependencyInjection.Microsoft", "src\PolylineAlgorithm.DependencyInjection.Microsoft\PolylineAlgorithm.DependencyInjection.Microsoft.csproj", "{2B0061B3-7B80-4101-9FF0-AD513AE4C4E5}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolylineAlgorithm.NetTopologySuite", "src\PolylineAlgorithm.NetTopologySuite\PolylineAlgorithm.NetTopologySuite.csproj", "{A5F4D456-3949-4146-95D2-E0208EEF207A}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -51,30 +39,6 @@ Global {9C7CBAD5-415B-4589-86E1-01C849F9C56C}.Debug|Any CPU.Build.0 = Debug|Any CPU {9C7CBAD5-415B-4589-86E1-01C849F9C56C}.Release|Any CPU.ActiveCfg = Release|Any CPU {9C7CBAD5-415B-4589-86E1-01C849F9C56C}.Release|Any CPU.Build.0 = Release|Any CPU - {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B}.Release|Any CPU.Build.0 = Release|Any CPU - {B4FD710A-E5B8-4467-8D0B-037A28132047}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B4FD710A-E5B8-4467-8D0B-037A28132047}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B4FD710A-E5B8-4467-8D0B-037A28132047}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B4FD710A-E5B8-4467-8D0B-037A28132047}.Release|Any CPU.Build.0 = Release|Any CPU - {F9CFF4B1-C9AB-4F94-ADF4-B29925E1187E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F9CFF4B1-C9AB-4F94-ADF4-B29925E1187E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F9CFF4B1-C9AB-4F94-ADF4-B29925E1187E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F9CFF4B1-C9AB-4F94-ADF4-B29925E1187E}.Release|Any CPU.Build.0 = Release|Any CPU - {9C1088DA-DBF7-4374-9775-C7613CCA98D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9C1088DA-DBF7-4374-9775-C7613CCA98D8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9C1088DA-DBF7-4374-9775-C7613CCA98D8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9C1088DA-DBF7-4374-9775-C7613CCA98D8}.Release|Any CPU.Build.0 = Release|Any CPU - {2B0061B3-7B80-4101-9FF0-AD513AE4C4E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2B0061B3-7B80-4101-9FF0-AD513AE4C4E5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2B0061B3-7B80-4101-9FF0-AD513AE4C4E5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2B0061B3-7B80-4101-9FF0-AD513AE4C4E5}.Release|Any CPU.Build.0 = Release|Any CPU - {A5F4D456-3949-4146-95D2-E0208EEF207A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A5F4D456-3949-4146-95D2-E0208EEF207A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A5F4D456-3949-4146-95D2-E0208EEF207A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A5F4D456-3949-4146-95D2-E0208EEF207A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -83,12 +47,6 @@ Global {882322A6-E758-4662-8D1C-7C555C8FC3F2} = {51C886AF-D610-48A4-9D73-2DEB38742801} {30324A08-AA42-425D-87DA-8F9C6AF60454} = {576FEFFC-B624-40C3-A8AF-4E5233802EA0} {9C7CBAD5-415B-4589-86E1-01C849F9C56C} = {33C03F16-4313-4579-87E6-65892AF21D7D} - {D9F175EA-6F4C-4BFF-AB1D-5F45324B6C1B} = {33C03F16-4313-4579-87E6-65892AF21D7D} - {B4FD710A-E5B8-4467-8D0B-037A28132047} = {576FEFFC-B624-40C3-A8AF-4E5233802EA0} - {F9CFF4B1-C9AB-4F94-ADF4-B29925E1187E} = {576FEFFC-B624-40C3-A8AF-4E5233802EA0} - {9C1088DA-DBF7-4374-9775-C7613CCA98D8} = {51C886AF-D610-48A4-9D73-2DEB38742801} - {2B0061B3-7B80-4101-9FF0-AD513AE4C4E5} = {51C886AF-D610-48A4-9D73-2DEB38742801} - {A5F4D456-3949-4146-95D2-E0208EEF207A} = {51C886AF-D610-48A4-9D73-2DEB38742801} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {93A268DC-0947-4FBB-B495-DDAD4B013D82} diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj index f4b46667..967519a1 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineAlgorithm.Benchmarks.csproj @@ -16,6 +16,9 @@ + + + diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs index 74990643..4f273324 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs @@ -8,6 +8,10 @@ namespace PolylineAlgorithm.Benchmarks; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Order; +using Cloudikka.PolylineAlgorithm.Encoding; +using PolylineAlgorithm; +using PolylinerNet; using System.Collections.Generic; [RankColumn] @@ -17,25 +21,55 @@ namespace PolylineAlgorithm.Benchmarks; [SimpleJob(RuntimeMoniker.Net70)] [SimpleJob(RuntimeMoniker.Net80)] [SimpleJob(RuntimeMoniker.Net90)] -[Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.Declared)] +[Orderer(SummaryOrderPolicy.Default)] public class PolylineBenchmark { private readonly Consumer _consumer = new(); + public static string String_Polyline { get; } = "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"; + public static ReadOnlyMemory Memory_Polyline { get; } = String_Polyline.AsMemory(); - public DefaultPolylineDecoder Decoder { get; } = new DefaultPolylineDecoder(); - public Polyline Polyline { get; } = new Polyline("}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"); + public static IEnumerable PolylineAlgorithm_Coordinates { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; + public static List PolylinerNet_PolylinePoint { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; + public static IEnumerable<(double, double)> Cloudikka_PolylineEncoding_Tuple { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; + + + + [Benchmark] + public void PolylineDecoder_Decode() { + ReadOnlySpan polyline = Memory_Polyline.Span; + var decoder = new PolylineDecoder(); + decoder.Decode(in polyline).Consume(_consumer); + } [Benchmark] - public Span Decode() - => Decoder - .Decode(Polyline); + public void Polyliner_Decode() { + string polyline = String_Polyline; + var polyliner = new Polyliner(); + polyliner.Decode(polyline).Consume(_consumer); + } + + [Benchmark] + public void Cloudikka_PolylineEncoding_Decode() { + string polyline = String_Polyline; + var polyliner = new PolylineEncoding(); + polyliner.Decode(polyline).Consume(_consumer); + } - public DefaultPolylineEncoder Encoder { get; } = new DefaultPolylineEncoder(); - public IEnumerable Coordinates { get; } = [Coordinate.Create(60.81071, -121.40005), Coordinate.Create(70.05664, -38.43130), Coordinate.Create(37.52379, -84.83755), Coordinate.Create(41.85003, 26.25620), Coordinate.Create(68.04709, 110.63120), Coordinate.Create(61.48922, 50.16245), Coordinate.Create(-4.46018, -58.11880), Coordinate.Create(-32.16061, -3.27505), Coordinate.Create(-50.89185, -55.30630), Coordinate.Create(-28.52070, 90.94370), Coordinate.Create(35.26009, 93.75620), Coordinate.Create(54.83622, 128.91245), Coordinate.Create(1.16022, 37.50620), Coordinate.Create(-44.26398, -131.24380), Coordinate.Create(-33.34325, 154.22495), Coordinate.Create(-59.65879, 90.94370), Coordinate.Create(-62.38215, 0.94370), Coordinate.Create(72.32117, 40.31870), Coordinate.Create(64.66910, 2.34995), Coordinate.Create(-61.04971, -84.83755), Coordinate.Create(77.10238, -91.86880), Coordinate.Create(-72.88859, -129.83755), Coordinate.Create(-69.24987, -24.36880), Coordinate.Create(77.41254, 119.06870), Coordinate.Create(-70.69409, 83.91245), Coordinate.Create(78.85650, 75.47495), Coordinate.Create(26.83989, 140.16245), Coordinate.Create(-24.75069, -108.74380), Coordinate.Create(30.53968, -145.30630), Coordinate.Create(79.12503, 145.78745), Coordinate.Create(-34.51006, 133.13120), Coordinate.Create(-73.29753, -60.93130), Coordinate.Create(-74.08712, 23.44370), Coordinate.Create(-76.57404, 100.78745), Coordinate.Create(-76.57404, 100.78745), Coordinate.Create(39.72082, 103.59995), Coordinate.Create(70.99412, 148.59995), Coordinate.Create(82.27591, 138.75620), Coordinate.Create(78.29964, -3.27505), Coordinate.Create(78.29964, -3.27505), Coordinate.Create(-8.65039, 47.34995)]; + [Benchmark] + public ReadOnlySpan PolylineEncoder_Encode() { + var encoder = new PolylineEncoder(); + return encoder.Encode(PolylineAlgorithm_Coordinates); + } + [Benchmark] + public string Polyliner_Encode() { + var polyliner = new Polyliner(); + return polyliner.Encode(PolylinerNet_PolylinePoint); + } [Benchmark] - public Polyline Encode() - => Encoder - .Encode(Coordinates); + public string Cloudikka_PolylineEncoding_Encode() { + var polyliner = new PolylineEncoding(); + return polyliner.Encode(Cloudikka_PolylineEncoding_Tuple); + } } diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs deleted file mode 100644 index f9a36eed..00000000 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Constants.cs +++ /dev/null @@ -1,78 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Implementation.Benchmarks { - /// - /// Defines global constant values - /// - internal static class Constants { - #region Constants - - /// - /// Defines the coordinate precision - /// - public const double Precision = 1E5; - - /// - /// Defines the shift length - /// - public const int ShiftLength = 5; - - #endregion - - /// - /// Defines ASCII characters constant values - /// - internal static class ASCII { - #region Constants - - /// - /// Defines the ASCII Question Mark - /// - public const int QuestionMark = 63; - - /// - /// Defines the ASCII Space - /// - public const int Space = 32; - - /// - /// Defines the ASCII Unit Separator - /// - public const int UnitSeparator = 31; - - #endregion - } - - /// - /// Defines coordinates constant values - /// - internal static class Coordinate { - #region Constants - - /// - /// Defines the maximum value for latitude - /// - public const int MaxLatitude = 90; - - /// - /// Defines the maximum value for longitude - /// - public const int MaxLongitude = 180; - - /// - /// Defines the minimum value for latitude - /// - public const int MinLatitude = -MaxLatitude; - - /// - /// Defines the minimum value for longitude - /// - public const int MinLongitude = -MaxLongitude; - - #endregion - } - } -} diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj deleted file mode 100644 index 44c51b5b..00000000 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineAlgorithm.Implementation.Benchmarks.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - Exe - net9.0 - 13.0 - enable - enable - true - en - pdbonly - true - - - - false - - - - - - - - - - - - - diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs deleted file mode 100644 index 96a93276..00000000 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineDecoderBenchmark.cs.cs +++ /dev/null @@ -1,598 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Implementation.Benchmarks; - -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Diagnosers; -using BenchmarkDotNet.Order; -using System; -using System.Collections.ObjectModel; -using System.Runtime.CompilerServices; - -[RankColumn] -[MemoryDiagnoser] -[RPlotExporter] -[EventPipeProfiler(EventPipeProfile.CpuSampling)] -[Orderer(SummaryOrderPolicy.Declared)] -public class PolylineDecoderBenchmark { - public static Dictionary Values() => - new Dictionary { - {1, "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"}, - {2, "}vwdGjafcRsvjKi}pxUhsrtCngtcAjjgzEdqvtLrscbKj}nr@wetlUc`nq]}_kfCyrfaK~wluUl`u}|@wa{lUmmuap@va{lU~oihCu||bF`|era@wsnnIjny{DxamaScqxza@dklDf{}kb@mtpeCavfzGqhx`Wyzzkm@jm`d@dba~Pppkg@h}pxU|rtnHp|flA|~xaPuykyN}fhv[h}pxUx~p}Ymx`sZih~iB{edwB"}, - {3, "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"} - }; - - [ParamsSource(nameof(Values))] - public KeyValuePair Polyline { get; set; } - - [Benchmark(Baseline = true)] - public Span Decode_Current() { - var decoder = new DefaultPolylineDecoder(); - return decoder.Decode(new Polyline(Polyline.Value)); - } - - [Benchmark] - public (double, double)[] Decode_V1() { - var decoder = new V1(); - return decoder.Decode(Polyline.Value).ToArray(); - } - - [Benchmark] - public (double, double)[] Decode_V2() { - var decoder = new V2(); - return decoder.Decode(Polyline.Value).ToArray(); - } - - [Benchmark] - public (double, double)[] Decode_V3() { - var decoder = new V3(); - return decoder.Decode(Polyline.Value).ToArray(); - } - - [Benchmark] - public (double, double)[] Decode_V4() { - var decoder = new V4(); - return decoder.Decode(Polyline.Value.AsMemory()).ToArray(); - } - - [Benchmark] - public (double, double)[] Decode_V5() { - var decoder = new V5(); - return decoder.Decode(Polyline.Value).ToArray(); - } - - [Benchmark] - public (double, double)[] Decode_V6() { - var decoder = new V6(); - return decoder.Decode(Polyline.Value).ToArray(); - } - - [Benchmark] - public (double, double)[] Decode_V7() { - var decoder = new V7(); - return decoder.Decode(Polyline.Value).ToArray(); - } - - private class V1 { - public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - if (polyline is null || polyline.Length == 0) { - throw new ArgumentException(nameof(polyline)); - } - - int index = 0; - int latitude = 0; - int longitude = 0; - - var result = new List<(double Latitude, double Longitude)>(); - - while (index < polyline.Length) { - if (!TryCalculateNext(ref polyline, ref index, ref latitude)) { - throw new InvalidOperationException(); - } - - if (!TryCalculateNext(ref polyline, ref index, ref longitude)) { - throw new InvalidOperationException(); - } - - var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); - - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(); - } - - result.Add(coordinate); - } - - return result; - } - - private static bool TryCalculateNext(ref string polyline, ref int index, ref int value) { - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - private static double GetDoubleRepresentation(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } - - public static class CoordinateValidator { - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - } - - private class V2 { - public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - if (polyline is null || polyline.Length == 0) { - throw new ArgumentException(nameof(polyline)); - } - - int offset = 0; - int latitude = 0; - int longitude = 0; - - while (offset < polyline.Length) { - if (!TryCalculateNext(ref polyline, ref offset, ref latitude)) { - throw new InvalidOperationException(); - } - - if (!TryCalculateNext(ref polyline, ref offset, ref longitude)) { - throw new InvalidOperationException(); - } - - var coordinate = (GetDoubleRepresentation(latitude), GetDoubleRepresentation(longitude)); - - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(); - } - - yield return (latitude, longitude); - } - } - - private static bool TryCalculateNext(ref string polyline, ref int offset, ref int value) { - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline[offset++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && offset < polyline.Length); - - if (offset >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - private static double GetDoubleRepresentation(int value) { - return value / Constants.Precision; - } - - public static class CoordinateValidator { - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - } - - private class V3 { - public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - // Checking null and at least one character - if (polyline == null || polyline.Length == 0) { - throw new ArgumentException(String.Empty, nameof(polyline)); - } - - // Initialize local variables - int index = 0; - int latitude = 0; - int longitude = 0; - - // Looping through encoded polyline char array - while (index < polyline.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref latitude)) { - throw new InvalidOperationException(String.Empty); - } - - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref longitude)) { - throw new InvalidOperationException(String.Empty); - } - - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - - // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(String.Empty); - } - - yield return coordinate; - - #region Local functions - - static bool TryCalculateNext(string polyline, ref int index, ref int value) { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - static double GetCoordinate(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } - - #endregion - } - } - - /// - /// Performs coordinate validation - /// - internal static class CoordinateValidator { - #region Methods - - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - - #endregion - } - } - - private class V4 { - public IEnumerable<(double Latitude, double Longitude)> Decode(ReadOnlyMemory polyline) { - // Checking null and at least one character - if (polyline.IsEmpty) { - throw new ArgumentException(String.Empty, nameof(polyline)); - } - - // Initialize local variable - int index = 0; - int latitude = 0; - int longitude = 0; - - // Looping through encoded polyline char array - while (index < polyline.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(ref polyline, ref index, ref latitude)) { - throw new InvalidOperationException(String.Empty); - } - - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(ref polyline, ref index, ref longitude)) { - throw new InvalidOperationException(String.Empty); - } - - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - - // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(String.Empty); - } - - yield return coordinate; - } - - static bool TryCalculateNext(ref ReadOnlyMemory polyline, ref int index, ref int value) { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline.Span[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - static double GetCoordinate(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } - } - - /// - /// Performs coordinate validation - /// - internal static class CoordinateValidator { - #region Methods - - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - - #endregion - } - } - - private class V5 { - public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - // Checking null and at least one character - if (polyline == null || polyline.Length == 0) { - throw new ArgumentException(String.Empty, nameof(polyline)); - } - - // Initialize local variable - ReadOnlyMemory memory = polyline.AsMemory(); - int index = 0; - int latitude = 0; - int longitude = 0; - - // Looping through encoded polyline char array - while (index < memory.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(ref memory, ref index, ref latitude)) { - throw new InvalidOperationException(String.Empty); - } - - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(ref memory, ref index, ref longitude)) { - throw new InvalidOperationException(String.Empty); - } - - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - - // Validating decoded coordinate. If not valid exception is thrown - if (!CoordinateValidator.IsValid(coordinate)) { - throw new InvalidOperationException(String.Empty); - } - - yield return coordinate; - } - - static bool TryCalculateNext(ref ReadOnlyMemory polyline, ref int index, ref int value) { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline.Span[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - static double GetCoordinate(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } - } - - /// - /// Performs coordinate validation - /// - internal static class CoordinateValidator { - #region Methods - - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - - #endregion - } - } - - private class V6 { - public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - // Checking null and at least one character - if (polyline == null || polyline.Length == 0) { - throw new ArgumentException(String.Empty, nameof(polyline)); - } - - // Initialize local variables - int index = 0; - int latitude = 0; - int longitude = 0; - - // Looping through encoded polyline char array - while (index < polyline.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref latitude)) { - throw new InvalidOperationException(String.Empty); - } - - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref longitude)) { - throw new InvalidOperationException(String.Empty); - } - - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - - yield return coordinate; - } - } - - private bool TryCalculateNext(string polyline, ref int index, ref int value) { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - private double GetCoordinate(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } - } - - private class V7 { - public IEnumerable<(double Latitude, double Longitude)> Decode(string polyline) { - // Checking null and at least one character - if (polyline == null || polyline.Length == 0) { - throw new ArgumentException(string.Empty, nameof(polyline)); - } - - // Initialize local variables - int index = 0; - int latitude = 0; - int longitude = 0; - - // Looping through encoded polyline char array - while (index < polyline.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref latitude)) { - throw new InvalidOperationException(string.Empty); - } - - // Attempting to calculate next longitude value. If failed exception is thrown - if (!TryCalculateNext(polyline, ref index, ref longitude)) { - throw new InvalidOperationException(string.Empty); - } - - var coordinate = (GetCoordinate(latitude), GetCoordinate(longitude)); - - yield return coordinate; - } - } - - static bool TryCalculateNext(string polyline, ref int index, ref int value) { - // Local variable initialization - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); - - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - static double GetCoordinate(int value) { - return Convert.ToDouble(value) / Constants.Precision; - } - } -} diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs deleted file mode 100644 index 256b95c9..00000000 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/PolylineEncoderBenchmark.cs +++ /dev/null @@ -1,819 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Implementation.Benchmarks; - -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Diagnosers; -using BenchmarkDotNet.Order; -using Microsoft.Extensions.ObjectPool; -using System.Collections.Generic; -using System.Text; - -[RankColumn] -[MemoryDiagnoser] -[RPlotExporter] -[EventPipeProfiler(EventPipeProfile.CpuSampling)] -[Orderer(SummaryOrderPolicy.Declared)] -public class PolylineEncoderBenchmark { - - public Dictionary Values => - new Dictionary { - {1, new[] { (49.47383, 59.06250), (-58.37407, 25.31250), (52.99363, -120.93750), (-44.49024, -174.37500) } }, - {2, new[] { (42.88895, -100.30630), (44.91513, 19.22495), (20.40244, 7.97495), (-15.52130, -63.74380), (-78.95116, -72.18130), (38.63072, 88.13120), (60.81071, 151.41245), (-58.20769, -173.43130), (59.40939, 83.91245), (-58.20769, 61.41245), (-20.86278, -119.99380), (34.10374, -150.93130), (-71.15367, 31.88120), (-72.04138, -153.74380), (-49.99635, -107.33755), (76.12614, 135.94370), (70.05664, 41.72495), (63.43879, -77.80630), (13.68456, -90.46255), (-75.90519, -7.49380), (74.71112, -127.02505), (-66.61109, 17.81870), (-49.08384, 37.50620) } }, - {3, new[] { (60.81071, -121.40005), (70.05664, -38.43130), (37.52379, -84.83755), (41.85003, 26.25620), (68.04709, 110.63120), (61.48922, 50.16245), (-4.46018, -58.11880), (-32.16061, -3.27505), (-50.89185, -55.30630), (-28.52070, 90.94370), (35.26009, 93.75620), (54.83622, 128.91245), (1.16022, 37.50620), (-44.26398, -131.24380), (-33.34325, 154.22495), (-59.65879, 90.94370), (-62.38215, 0.94370), (72.32117, 40.31870), (64.66910, 2.34995), (-61.04971, -84.83755), (77.10238, -91.86880), (-72.88859, -129.83755), (-69.24987, -24.36880), (77.41254, 119.06870), (-70.69409, 83.91245), (78.85650, 75.47495), (26.83989, 140.16245), (-24.75069, -108.74380), (30.53968, -145.30630), (79.12503, 145.78745), (-34.51006, 133.13120), (-73.29753, -60.93130), (-74.08712, 23.44370), (-76.57404, 100.78745), (-76.57404, 100.78745), (39.72082, 103.59995), (70.99412, 148.59995), (82.27591, 138.75620), (78.29964, -3.27505), (78.29964, -3.27505), (-8.65039, 47.34995) } } - }; - - - [ParamsSource(nameof(Values))] - public KeyValuePair Coordinates { get; set; } - - [Benchmark(Baseline = true)] - public Polyline Encode_Current() { - var encoder = new DefaultPolylineEncoder(); - var result = encoder.Encode(Coordinates.Value.Select(v => Coordinate.Create(v.Item1, v.Item2))); - return result; - } - - [Benchmark] - public string Encode_V1() { - var encoder = new V1(); - var result = encoder.Encode(Coordinates.Value); - return result; - } - - [Benchmark] - [ArgumentsSource(nameof(Values))] - public string Encode_V2() { - var encoder = new V2(); - var result = encoder.Encode(Coordinates.Value); - return result; - } - - [Benchmark] - [ArgumentsSource(nameof(Values))] - public string Encode_V3() { - var encoder = new V3(); - var result = encoder.Encode(Coordinates.Value); - return result; - } - - [Benchmark] - [ArgumentsSource(nameof(Values))] - public string Encode_V4() { - var encoder = new V4(); - var result = encoder.Encode(Coordinates.Value); - return result; - } - - [Benchmark] - [ArgumentsSource(nameof(Values))] - public string Encode_V5() { - var encoder = new V5(); - var result = encoder.Encode(Coordinates.Value); - return result; - } - - [Benchmark] - [ArgumentsSource(nameof(Values))] - public string Encode_V6() { - var encoder = new V6(); - var result = encoder.Encode(Coordinates.Value); - return result; - } - - [Benchmark] - [ArgumentsSource(nameof(Values))] - public string Encode_V7() { - var encoder = new V7(); - var result = encoder.Encode(Coordinates.Value); - return result; - } - - private class V1 { - public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates is null || !coordinates.Any()) { - throw new ArgumentException(nameof(coordinates)); - } - - EnsureCoordinates(coordinates); - - int lastLatitude = 0; - int lastLongitude = 0; - var sb = new StringBuilder(); - - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = GetIntegerRepresentation(Latitude); - int longitude = GetIntegerRepresentation(Longitude); - - sb.Append(GetEncodedCharacters(latitude - lastLatitude).ToArray()); - sb.Append(GetEncodedCharacters(longitude - lastLongitude).ToArray()); - - lastLatitude = latitude; - lastLongitude = longitude; - } - - return sb.ToString(); - } - - private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) { - var invalidCoordinates = coordinates - .Where(c => !CoordinateValidator.IsValid(c)); - - if (invalidCoordinates.Any()) { - throw new AggregateException( - invalidCoordinates - .Select(c => - new ArgumentOutOfRangeException() - ) - ); - } - } - - private static IEnumerable GetEncodedCharacters(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } - - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - private static int GetIntegerRepresentation(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - public static class CoordinateValidator { - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - } - - private class V2 { - private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, int.MaxValue); - - public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates is null || !coordinates.Any()) { - throw new ArgumentException(nameof(coordinates)); - } - - EnsureCoordinates(coordinates); - - int previousLatitude = 0; - int previousLongitude = 0; - - var sb = _pool.Get(); - - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = GetIntegerRepresentation(Latitude); - int longitude = GetIntegerRepresentation(Longitude); - - sb.Append(GetEncodedCharacters(latitude - previousLatitude).ToArray()); - sb.Append(GetEncodedCharacters(longitude - previousLongitude).ToArray()); - - previousLatitude = latitude; - previousLongitude = longitude; - } - - var result = sb.ToString(); - - _pool.Return(sb); - - return result; - } - - private static void EnsureCoordinates(IEnumerable<(double Latitude, double Longitude)> coordinates) { - var invalidCoordinates = coordinates - .Where(c => !CoordinateValidator.IsValid(c)); - - if (invalidCoordinates.Any()) { - throw new AggregateException( - invalidCoordinates - .Select(c => - new ArgumentOutOfRangeException() - ) - ); - } - } - - private static IEnumerable GetEncodedCharacters(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } - - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - private static int GetIntegerRepresentation(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - public static class CoordinateValidator { - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - } - - private class V3 { - /// - /// Method encodes coordinates to polyline encoded representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(); - } - - // Validate collection of coordinates - if (!TryValidate(coordinates, out var exceptions)) { - throw new AggregateException(exceptions); - } - - // Initializing local variables - int previousLatitude = 0; - int previousLongitude = 0; - var sb = new StringBuilder(coordinates.Count() * 4); - - // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(Latitude); - int longitude = Round(Longitude); - - sb.Append(GetSequence(latitude - previousLatitude).ToArray()); - sb.Append(GetSequence(longitude - previousLongitude).ToArray()); - - previousLatitude = latitude; - previousLongitude = longitude; - } - - return sb.ToString(); - - #region Local functions - - bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, out ICollection exceptions) { - exceptions = new List(collection.Count()); - - foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } - } - - return !exceptions.GetEnumerator().MoveNext(); - } - - int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - IEnumerable GetSequence(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } - - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - #endregion - } - - public static class CoordinateValidator { - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - /// - /// Performs latitude validation - /// - /// Latitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - /// - /// Performs longitude validation - /// - /// Longitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - - public class CoordinateValidationException(double latitude, double longitude) - : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { - public double Latitude { get; } - - public double Longitude { get; } - } - } - - private class V4 { - private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); - - /// - /// Method encodes coordinates to polyline encoded representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(); - } - - int count = coordinates.Count(); - ICollection exceptions = new List(count); - - // Validate collection of coordinates - if (!TryValidate(coordinates, ref exceptions)) { - throw new AggregateException(exceptions); - } - - // Initializing local variables - int previousLatitude = 0; - int previousLongitude = 0; - var sb = _pool.Get(); - - // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(Latitude); - int longitude = Round(Longitude); - - sb.Append(GetSequence(latitude - previousLatitude).ToArray()); - sb.Append(GetSequence(longitude - previousLongitude).ToArray()); - - previousLatitude = latitude; - previousLongitude = longitude; - } - - return sb.ToString(); - - #region Local functions - - bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { - foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } - } - - return exceptions.Count == 0; - } - - int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - IEnumerable GetSequence(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } - - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - #endregion - } - - public static class CoordinateValidator { - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - /// - /// Performs latitude validation - /// - /// Latitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - /// - /// Performs longitude validation - /// - /// Longitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - - public class CoordinateValidationException(double latitude, double longitude) - : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { - public double Latitude { get; } - - public double Longitude { get; } - } - } - - private class V5 { - private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); - - /// - /// Method encodes coordinates to polyline encoded representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(); - } - - int count = coordinates.Count(); - ICollection exceptions = new List(count); - - // Validate collection of coordinates - if (!TryValidate(coordinates, ref exceptions)) { - throw new AggregateException(exceptions); - } - - // Initializing local variables - int previousLatitude = 0; - int previousLongitude = 0; - var sb = _pool.Get(); - - // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(Latitude); - int longitude = Round(Longitude); - - sb.Append(GetSequence(latitude - previousLatitude).ToArray()); - sb.Append(GetSequence(longitude - previousLongitude).ToArray()); - - previousLatitude = latitude; - previousLongitude = longitude; - } - - return sb.ToString(); - - #region Local functions - - bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { - foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } - } - - return exceptions.Count == 0; - } - - int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - IEnumerable GetSequence(int value) { - int shifted = value << 1; - if (value < 0) - shifted = ~shifted; - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - yield return (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - - rem >>= Constants.ShiftLength; - } - - yield return (char)(rem + Constants.ASCII.QuestionMark); - } - - #endregion - } - - public static class CoordinateValidator { - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - /// - /// Performs latitude validation - /// - /// Latitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - /// - /// Performs longitude validation - /// - /// Longitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - - public class CoordinateValidationException(double latitude, double longitude) - : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { - public double Latitude { get; } - - public double Longitude { get; } - } - } - - private class V6 { - /// - /// Method encodes coordinates to polyline encoded representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(); - } - - int count = coordinates.Count(); - ICollection exceptions = new List(count); - - // Validate collection of coordinates - if (!TryValidate(coordinates, ref exceptions)) { - throw new AggregateException(exceptions); - } - - // Initializing local variables - int index = 0; - Memory buffer = new char[count * 12]; - int previousLatitude = 0; - int previousLongitude = 0; - - // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(Latitude); - int longitude = Round(Longitude); - - WriteNext(ref buffer, ref index, ref latitude, ref previousLatitude); - WriteNext(ref buffer, ref index, ref longitude, ref previousLongitude); - } - - return buffer[..index].ToString(); - } - - bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { - foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } - } - - return exceptions.Count == 0; - } - - int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { - int value = current - previous; - int shifted = value << 1; - - if (value < 0) { - shifted = ~shifted; - } - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - rem >>= Constants.ShiftLength; - index++; - } - - buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); - - index++; - - previous = current; - } - - public static class CoordinateValidator { - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - /// - /// Performs latitude validation - /// - /// Latitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - /// - /// Performs longitude validation - /// - /// Longitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - - public class CoordinateValidationException(double latitude, double longitude) - : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { - public double Latitude { get; } - - public double Longitude { get; } - } - } - - private class V7 { - /// - /// Method encodes coordinates to polyline encoded representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null or empty enumerable - /// If one or more coordinate is out of range - public string Encode(IEnumerable<(double Latitude, double Longitude)> coordinates) { - if (coordinates == null || !coordinates.GetEnumerator().MoveNext()) { - throw new ArgumentException(); - } - - int count = coordinates.Count(); - ICollection exceptions = new List(count); - - // Validate collection of coordinates - if (!TryValidate(coordinates, ref exceptions)) { - throw new AggregateException(exceptions); - } - - // Initializing local variables - int index = 0; - Memory buffer = new char[count * 12]; - int previousLatitude = 0; - int previousLongitude = 0; - - // Looping over coordinates and building encoded result - foreach (var (Latitude, Longitude) in coordinates) { - int latitude = Round(Latitude); - int longitude = Round(Longitude); - - WriteNext(ref buffer, ref index, ref latitude, ref previousLatitude); - WriteNext(ref buffer, ref index, ref longitude, ref previousLongitude); - } - - return buffer[..index].ToString(); - - #region Local functions - - static bool TryValidate(IEnumerable<(double Latitude, double Longitude)> collection, ref ICollection exceptions) { - foreach (var item in collection) { - if (!CoordinateValidator.IsValid(item)) { - exceptions.Add(new CoordinateValidationException(item.Latitude, item.Longitude)); - } - } - - return exceptions.Count == 0; - } - - static int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - static void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { - int value = current - previous; - int shifted = value << 1; - - if (value < 0) { - shifted = ~shifted; - } - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - rem >>= Constants.ShiftLength; - index++; - } - - buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); - - index++; - - previous = current; - } - #endregion - } - - public static class CoordinateValidator { - /// - /// Performs coordinate validation - /// - /// Coordinate to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValid((double Latitude, double Longitude) coordinate) { - return IsValidLatitude(coordinate.Latitude) && IsValidLongitude(coordinate.Longitude); - } - - /// - /// Performs latitude validation - /// - /// Latitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLatitude(double latitude) { - return latitude >= Constants.Coordinate.MinLatitude && latitude <= Constants.Coordinate.MaxLatitude; - } - - /// - /// Performs longitude validation - /// - /// Longitude value to validate - /// Returns validation result. If valid then true, otherwise false. - public static bool IsValidLongitude(double longitude) { - return longitude >= Constants.Coordinate.MinLongitude && longitude <= Constants.Coordinate.MaxLongitude; - } - } - - public class CoordinateValidationException(double latitude, double longitude) - : Exception(string.Format("Latitude {0} or longitude {1} is not valid. Latitude must be in range between -90 and +90. Longitude must be in range between -180 and +180.", latitude, longitude)) { - public double Latitude { get; } - - public double Longitude { get; } - } - } -} diff --git a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs deleted file mode 100644 index 87f9c8c7..00000000 --- a/benchmarks/PolylineAlgorithm.Implementation.Benchmarks/Program.cs +++ /dev/null @@ -1,18 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Implementation.Benchmarks; - -using BenchmarkDotNet.Configs; -using BenchmarkDotNet.Running; - -internal class Program { - static void Main(string[] args) { - BenchmarkRunner - .Run(); - BenchmarkRunner - .Run(); - } -} diff --git a/src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs b/src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs deleted file mode 100644 index 062bff12..00000000 --- a/src/PolylineAlgorithm.DependencyInjection.Autofac/ContainerBuilderExtensions.cs +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.DependencyInjection.Autofac; - -using global::Autofac; -using PolylineAlgorithm.Abstraction; - -public static class ContainerBuilderExtensions { - /// - /// Registers singleton instances of - /// - /// and - /// into . - /// - /// Instance of to register polyline services into. - /// - /// TCoordinate is . - /// - public static void RegisterDefaultPolylineAlgorithm(this ContainerBuilder builder) { - builder.RegisterType() - .As>() - .SingleInstance(); - - builder.RegisterType() - .As>() - .SingleInstance(); - } -} diff --git a/src/PolylineAlgorithm.DependencyInjection.Autofac/PolylineAlgorithm.DependencyInjection.Autofac.csproj b/src/PolylineAlgorithm.DependencyInjection.Autofac/PolylineAlgorithm.DependencyInjection.Autofac.csproj deleted file mode 100644 index f9cf1337..00000000 --- a/src/PolylineAlgorithm.DependencyInjection.Autofac/PolylineAlgorithm.DependencyInjection.Autofac.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - netstandard2.1 - 13.0 - enable - enable - true - - - - All - latest - true - true - true - - - - - - - - - - - diff --git a/src/PolylineAlgorithm.DependencyInjection.Microsoft/PolylineAlgorithm.DependencyInjection.Microsoft.csproj b/src/PolylineAlgorithm.DependencyInjection.Microsoft/PolylineAlgorithm.DependencyInjection.Microsoft.csproj deleted file mode 100644 index f4a94487..00000000 --- a/src/PolylineAlgorithm.DependencyInjection.Microsoft/PolylineAlgorithm.DependencyInjection.Microsoft.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - netstandard2.1 - 13.0 - enable - enable - true - - - - All - latest - true - true - true - - - - - - - - - - - diff --git a/src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs b/src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs deleted file mode 100644 index 77737c09..00000000 --- a/src/PolylineAlgorithm.DependencyInjection.Microsoft/ServiceCollectionExtensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.DependencyInjection.Microsoft; - -using global::Microsoft.Extensions.DependencyInjection; -using PolylineAlgorithm.Abstraction; - -public static class ServiceCollectionExtensions { - /// - /// Adds a singleton service of the type specified in and - /// with an implementation type and - /// to the specified . - /// - /// The to add the services to. - /// A reference to instance after the operation has completed.. - /// - /// TCoordinate is . - /// - public static IServiceCollection AddDefaultPolylineAlgorithm(this IServiceCollection services) { - return services - .AddSingleton, DefaultPolylineEncoder>() - .AddSingleton, DefaultPolylineDecoder>(); - - } -} diff --git a/src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineDecoder.cs b/src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineDecoder.cs deleted file mode 100644 index 3cd8470c..00000000 --- a/src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineDecoder.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace PolylineAlgorithm.NetTopologySuite; - -using global::NetTopologySuite.Geometries; -using PolylineAlgorithm.Abstraction; - -/// -public sealed class NetTopologyPolylineDecoder : PolylineDecoder { - protected override Point CreateCoordinate(ref readonly double latitude, ref readonly double longitude) { - return new Point(latitude, longitude); - } -} diff --git a/src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineEncoder.cs b/src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineEncoder.cs deleted file mode 100644 index b253eb7d..00000000 --- a/src/PolylineAlgorithm.NetTopologySuite/NetTopologyPolylineEncoder.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace PolylineAlgorithm.NetTopologySuite; - -using global::NetTopologySuite.Geometries; -using PolylineAlgorithm.Abstraction; -using System; - -/// -public sealed class NetTopologyPolylineEncoder : PolylineEncoder { - protected override double GetLatitude(ref readonly Coordinate coordinate) { - ArgumentNullException.ThrowIfNull(coordinate); - - return coordinate.X; - } - - protected override double GetLongitude(ref readonly Coordinate coordinate) { - ArgumentNullException.ThrowIfNull(coordinate); - - return coordinate.Y; - } -} diff --git a/src/PolylineAlgorithm.NetTopologySuite/PolylineAlgorithm.NetTopologySuite.csproj b/src/PolylineAlgorithm.NetTopologySuite/PolylineAlgorithm.NetTopologySuite.csproj deleted file mode 100644 index 10122e51..00000000 --- a/src/PolylineAlgorithm.NetTopologySuite/PolylineAlgorithm.NetTopologySuite.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - net8.0 - 13.0 - enable - enable - true - - - - All - latest - true - true - true - - - - - - - - - - - diff --git a/src/PolylineAlgorithm/Abstraction/IPolylineDecoder.cs b/src/PolylineAlgorithm/Abstraction/IPolylineDecoder.cs deleted file mode 100644 index 54352703..00000000 --- a/src/PolylineAlgorithm/Abstraction/IPolylineDecoder.cs +++ /dev/null @@ -1,20 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Abstraction; - -using System.Collections.ObjectModel; - -/// -/// Converts an encoded polyline string into a set of latitude and longitude coordinates. -/// -public interface IPolylineDecoder { - /// - /// Decodes an encoded polyline string into a set of . - /// - /// An encoded polyline string to decode. - /// A decoded polyline. - Span Decode(Polyline polyline); -} \ No newline at end of file diff --git a/src/PolylineAlgorithm/Abstraction/IPolylineEncoder.cs b/src/PolylineAlgorithm/Abstraction/IPolylineEncoder.cs deleted file mode 100644 index 801a425c..00000000 --- a/src/PolylineAlgorithm/Abstraction/IPolylineEncoder.cs +++ /dev/null @@ -1,20 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Abstraction; - -using System.Collections.Generic; - -/// -/// Converts a set of latitude and longitude coordinates into an encoded polyline string. -/// -public interface IPolylineEncoder { - /// - /// Encodes a set of value tuples representing latitude and longitude coordinates into an encoded polyline string. - /// - /// A set of value tuples representing latitude and longitude coordinates. - /// An encoded polyline string representing a set of latitude and longitude coordinates. - Polyline Encode(IEnumerable coordinates); -} \ No newline at end of file diff --git a/src/PolylineAlgorithm/Abstraction/PolylineDecoder.cs b/src/PolylineAlgorithm/Abstraction/PolylineDecoder.cs deleted file mode 100644 index 0423983d..00000000 --- a/src/PolylineAlgorithm/Abstraction/PolylineDecoder.cs +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Abstraction; - -using PolylineAlgorithm.Internal; - -/// -/// A coordinate validator. -public abstract class PolylineDecoder : IPolylineDecoder { - - /// - /// Thrown when argument is null -or- empty. - /// Thrown when is not in correct format. - public Span Decode(Polyline polyline) { - // Checking null and at least one character - if (polyline.IsEmpty) { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullEmptyOrWhitespace, nameof(polyline)); - } - - // Initialize local variables - int position = 0; - int roundedLatitude = 0; - int roundedLongitude = 0; - int count = (int)Math.Ceiling(polyline.Length / 8d); - Span coordinates = new TCoordinate[count]; - int index = 0; - - // Looping through encoded polyline char array - while (position < polyline.Length) { - // Attempting to calculate next latitude value. If failed exception is thrown. - if (!TryDecodeNext(ref polyline, ref position, ref roundedLatitude)) { - throw new InvalidOperationException(ExceptionMessageResource.PolylineStringIsMalformed); - } - - // Attempting to calculate next longitude value. If failed exception is thrown. - if (!TryDecodeNext(ref polyline, ref position, ref roundedLongitude)) { - throw new InvalidOperationException(ExceptionMessageResource.PolylineStringIsMalformed); - } - - double latitude = Precise(ref roundedLatitude); - double longitude = Precise(ref roundedLongitude); - - coordinates[index] = CreateCoordinate(in latitude, in longitude); - index++; - } - - return coordinates[..index]; - } - - static bool TryDecodeNext(ref Polyline polyline, ref int position, ref int value) { - // Initialize local variables - int chunk; - int sum = 0; - int shifter = 0; - - do { - chunk = polyline[position++] - Constants.ASCII.QuestionMark; - sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; - shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && position < polyline.Length); - - if (position >= polyline.Length && chunk >= Constants.ASCII.Space) - return false; - - value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; - - return true; - } - - private static double Precise(ref int value) { - return Convert.ToDouble(value) / Constants.Precision; - } - - /// - /// Creates an instance of - /// - /// A latitude value - /// A longitude value - /// An instance of - protected abstract TCoordinate CreateCoordinate(ref readonly double latitude, ref readonly double longitude); -} \ No newline at end of file diff --git a/src/PolylineAlgorithm/Abstraction/PolylineEncoder.cs b/src/PolylineAlgorithm/Abstraction/PolylineEncoder.cs deleted file mode 100644 index 548b06e2..00000000 --- a/src/PolylineAlgorithm/Abstraction/PolylineEncoder.cs +++ /dev/null @@ -1,90 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.Abstraction; - -using PolylineAlgorithm.Internal; -using System; -using System.Collections.Generic; -using System.Linq; - -/// -/// Performs polyline algorithm decoding and encoding -/// -public abstract class PolylineEncoder() : IPolylineEncoder { - //public ICoordinateValidator Validator { get; } = validator ?? throw new ArgumentNullException(nameof(validator)); - - /// - /// Encodes coordinates to polyline representation - /// - /// Coordinates to encode - /// Polyline encoded representation - /// If coordinates parameter is null - /// If coordinates parameter is empty - /// If one or more coordinate is out of valid range - public Polyline Encode(IEnumerable coordinates) { - if (coordinates is null) { - throw new ArgumentNullException(nameof(coordinates)); - } - - Span temp = coordinates.ToArray(); - - if (temp.IsEmpty) { - throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeEmptyEnumerable, nameof(coordinates)); - } - - // Initializing local variables - int index = 0; - Memory buffer = new char[GetSafeBufferSize(temp.Length)]; - int initialLatitude = 0; - int initialLongitude = 0; - - // Looping over coordinates and building encoded result - foreach (var coordinate in temp) { - int latitude = Round(GetLatitude(in coordinate)); - int longitude = Round(GetLongitude(in coordinate)); - - WriteNext(ref buffer, ref index, ref latitude, ref initialLatitude); - WriteNext(ref buffer, ref index, ref longitude, ref initialLongitude); - } - - return new Polyline(buffer[..index]); - } - - // Each coordinate consist of two values, each one is 4 or 5 chars long - // We use 12 = [2 coordinate values * 6 characters per each] to create safe buffer size - static int GetSafeBufferSize(int count) => count * 12; - - protected abstract double GetLatitude(ref readonly TCoordinate coordinate); - - protected abstract double GetLongitude(ref readonly TCoordinate coordinate); - - static int Round(double value) { - return (int)Math.Round(value * Constants.Precision); - } - - static void WriteNext(ref Memory buffer, ref int index, ref int current, ref int previous) { - int value = current - previous; - int shifted = value << 1; - - if (value < 0) { - shifted = ~shifted; - } - - int rem = shifted; - - while (rem >= Constants.ASCII.Space) { - buffer.Span[index] = (char)((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); - rem >>= Constants.ShiftLength; - index++; - } - - buffer.Span[index] = (char)(rem + Constants.ASCII.QuestionMark); - - index++; - - previous = current; - } -} diff --git a/src/PolylineAlgorithm/Coordinate.cs b/src/PolylineAlgorithm/Coordinate.cs index d9b04e18..2f4c0048 100644 --- a/src/PolylineAlgorithm/Coordinate.cs +++ b/src/PolylineAlgorithm/Coordinate.cs @@ -6,84 +6,55 @@ namespace PolylineAlgorithm; using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +[DebuggerDisplay(@"Latitude: {Latitude}, Longitude: {Longitude}")] +[StructLayout(LayoutKind.Sequential, Pack = 8, Size = 16)] public readonly struct Coordinate : IEquatable { - private static CoordinateRange ValidLatitude { get; } = new CoordinateRange(-90d, 90d); - private static CoordinateRange ValidLongitude { get; } = new CoordinateRange(-180d, 180d); - - public static Coordinate Create(double latitude, double longitude) { - ValidateCoordinate(ref latitude, ref longitude, out var exceptions); - - if (exceptions.Count == 0) { - return new Coordinate(latitude, longitude); - } else if (exceptions.Count == 1) { - throw exceptions[0]; - } else { - throw new AggregateException(exceptions); - } - - static void ValidateCoordinate(ref double latitude, ref double longitude, out List exceptions) { - exceptions = new List(2); - - if (!ValidLatitude.IsInRange(latitude)) { - exceptions.Add(new ArgumentException()); - } - - if (!ValidLongitude.IsInRange(longitude)) { - exceptions.Add(new ArgumentException()); - } - } - } - /// /// Initialized default instance of . /// - /// Use to initialize non-default instance. public Coordinate() { Latitude = 0d; Longitude = 0d; } - private Coordinate(double latitude, double longitude) { + public Coordinate(double latitude, double longitude) { Latitude = latitude; Longitude = longitude; } - public double Latitude { get; } - public double Longitude { get; } + public readonly double Latitude { get; } + public readonly double Longitude { get; } public bool IsDefault => Latitude == default && Longitude == default; - public override bool Equals(object? obj) - => obj is Coordinate coordinate && Equals(coordinate); - - public bool Equals(Coordinate other) - => Latitude == other.Latitude - && Longitude == other.Longitude; + public bool IsValid + => CoordinateValidator.Latitude.IsInRange(Latitude) + && CoordinateValidator.Longitude.IsInRange(Longitude); - public override int GetHashCode() - => HashCode.Combine(Latitude, Longitude); - public static bool operator ==(Coordinate left, Coordinate right) - => left.Equals(right); + public override bool Equals(object? obj) { + return obj is Coordinate coordinate && Equals(coordinate); + } - public static bool operator !=(Coordinate left, Coordinate right) - => !(left == right); + public bool Equals(Coordinate other) { + return Latitude == other.Latitude && + Longitude == other.Longitude; + } - private readonly struct CoordinateRange { - public CoordinateRange(double min, double max) { - if (min >= max) { - throw new ArgumentException(); - } + public override int GetHashCode() { + return HashCode.Combine(Latitude, Longitude); + } - Min = min; - Max = max; - } - public double Min { get; } - public double Max { get; } + public static bool operator ==(Coordinate left, Coordinate right) { + return left.Equals(right); + } - public bool IsInRange(double value) => value >= Min && value <= Max; + public static bool operator !=(Coordinate left, Coordinate right) { + return !(left == right); } } diff --git a/src/PolylineAlgorithm/CoordinateRange.cs b/src/PolylineAlgorithm/CoordinateRange.cs new file mode 100644 index 00000000..49963cbf --- /dev/null +++ b/src/PolylineAlgorithm/CoordinateRange.cs @@ -0,0 +1,46 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; + +using System; +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential, Pack = 8, Size = 16)] +public readonly struct CoordinateRange : IEquatable { + public CoordinateRange(double min, double max) { + if (min >= max) { + throw new ArgumentException(); + } + + Min = min; + Max = max; + } + public readonly double Min { get; } + public readonly double Max { get; } + + public override bool Equals(object? obj) { + return obj is CoordinateRange range && Equals(range); + } + + public bool Equals(CoordinateRange other) { + return Min == other.Min && + Max == other.Max; + } + + public override int GetHashCode() { + return HashCode.Combine(Min, Max); + } + + public bool IsInRange(double value) => value >= Min && value <= Max; + + public static bool operator ==(CoordinateRange left, CoordinateRange right) { + return left.Equals(right); + } + + public static bool operator !=(CoordinateRange left, CoordinateRange right) { + return !(left == right); + } +} diff --git a/src/PolylineAlgorithm/CoordinateValidator.cs b/src/PolylineAlgorithm/CoordinateValidator.cs new file mode 100644 index 00000000..b7e82c15 --- /dev/null +++ b/src/PolylineAlgorithm/CoordinateValidator.cs @@ -0,0 +1,11 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; + +public static class CoordinateValidator { + public static CoordinateRange Latitude { get; } = new CoordinateRange(-90d, 90d); + public static CoordinateRange Longitude { get; } = new CoordinateRange(-180d, 180d); +} diff --git a/src/PolylineAlgorithm/DefaultPolylineDecoder.cs b/src/PolylineAlgorithm/DefaultPolylineDecoder.cs deleted file mode 100644 index ffecf21e..00000000 --- a/src/PolylineAlgorithm/DefaultPolylineDecoder.cs +++ /dev/null @@ -1,15 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm; - -using PolylineAlgorithm.Abstraction; - -/// -public sealed class DefaultPolylineDecoder : PolylineDecoder { - protected override Coordinate CreateCoordinate(ref readonly double latitude, ref readonly double longitude) { - return Coordinate.Create(latitude, longitude); - } -} \ No newline at end of file diff --git a/src/PolylineAlgorithm/DefaultPolylineEncoder.cs b/src/PolylineAlgorithm/DefaultPolylineEncoder.cs deleted file mode 100644 index 28257a65..00000000 --- a/src/PolylineAlgorithm/DefaultPolylineEncoder.cs +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm; - -using PolylineAlgorithm.Abstraction; - -/// -/// Performs polyline algorithm decoding and encoding -/// -public sealed class DefaultPolylineEncoder() : PolylineEncoder { - protected override double GetLatitude(ref readonly Coordinate coordinate) { - return coordinate.Latitude; - } - - protected override double GetLongitude(ref readonly Coordinate coordinate) { - return coordinate.Longitude; - } -} diff --git a/src/PolylineAlgorithm/Internal/PolylineReader.cs b/src/PolylineAlgorithm/Internal/PolylineReader.cs new file mode 100644 index 00000000..27852080 --- /dev/null +++ b/src/PolylineAlgorithm/Internal/PolylineReader.cs @@ -0,0 +1,83 @@ +namespace PolylineAlgorithm.Internal; + +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Auto)] +internal ref struct PolylineReader { + private ReaderState _state = new(); + private ReadOnlySpan _polyline; + + public PolylineReader(ref readonly ReadOnlySpan polyline) { + _polyline = polyline; + } + + public readonly bool CanRead => _state.Position < _polyline.Length; + + public Coordinate Read() { + int latitude = _state.Latitude; + int longitude = _state.Longitude; + + DecodeNext(ref latitude, ref _polyline, ref _state); + DecodeNext(ref longitude, ref _polyline, ref _state); + + _state.SetLatitude(in latitude); + _state.SetLongitude(in longitude); + + Coordinate coordinate = new(Precise(ref latitude), Precise(ref longitude)); + + if (!coordinate.IsValid) { + throw new InvalidOperationException(); + } + + return coordinate; + + static double Precise(ref int value) { + return Convert.ToDouble(value) / Constants.Precision; + } + } + + static void DecodeNext(ref int value, ref ReadOnlySpan polyline, ref ReaderState state) { + // Initialize local variables + int chunk; + int sum = 0; + int shifter = 0; + + do { + chunk = polyline[state.Position] - Constants.ASCII.QuestionMark; + sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; + shifter += Constants.ShiftLength; + state.Advance(); + } while (chunk >= Constants.ASCII.Space && state.Position < polyline.Length); + + if (state.Position >= polyline.Length && chunk >= Constants.ASCII.Space) { + throw new InvalidOperationException(ExceptionMessageResource.PolylineStringIsMalformed); + } + + value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; + } + + [StructLayout(LayoutKind.Sequential, Pack = 4, Size = 12)] + private ref struct ReaderState { + public ReaderState() { + Position = Latitude = Longitude = 0; + } + + internal int Position { get; private set; } + + internal int Latitude { get; private set; } + + internal int Longitude { get; private set; } + + internal void Advance() { + Position += 1; + } + + internal void SetLatitude(ref readonly int latitude) { + Latitude = latitude; + } + + internal void SetLongitude(ref readonly int longitude) { + Longitude = longitude; + } + } +} \ No newline at end of file diff --git a/src/PolylineAlgorithm/Internal/PolylineWriter.cs b/src/PolylineAlgorithm/Internal/PolylineWriter.cs new file mode 100644 index 00000000..9bccc521 --- /dev/null +++ b/src/PolylineAlgorithm/Internal/PolylineWriter.cs @@ -0,0 +1,77 @@ +namespace PolylineAlgorithm.Internal; + +using System; +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Auto)] +internal ref struct PolylineWriter(ref readonly Span buffer) { + private WriterState _state = new(); + private Span _buffer = buffer; + + public void Write(ref readonly Coordinate coordinate) { + var latitude = Round(coordinate.Latitude); + var longitude = Round(coordinate.Longitude); + + var latDiff = latitude - _state.ExchangeLatitude(ref latitude); + var longDiff = longitude - _state.ExchangeLongitude(ref longitude); + + EncodeNext(ref latDiff, ref _buffer, ref _state); + EncodeNext(ref longDiff, ref _buffer, ref _state); + + static int Round(double value) { + return Convert.ToInt32(Math.Round(value * Constants.Precision)); + } + } + + static void EncodeNext(ref int value, ref Span buffer, ref WriterState state) { + int shifted = value << 1; + + if (value < 0) { + shifted = ~shifted; + } + + int rem = shifted; + + while (rem >= Constants.ASCII.Space) { + buffer[state.Position] = Convert.ToChar((Constants.ASCII.Space | rem & Constants.ASCII.UnitSeparator) + Constants.ASCII.QuestionMark); + state.Advance(); + rem >>= Constants.ShiftLength; + } + + buffer[state.Position] = Convert.ToChar(rem + Constants.ASCII.QuestionMark); + state.Advance(); + } + + public override readonly string ToString() { + return _buffer[.._state.Position].ToString(); + } + + [StructLayout(LayoutKind.Sequential, Pack = 4, Size = 12)] + private ref struct WriterState { + public WriterState() { + Position = Latitude = Longitude = 0; + } + + internal int Position { get; private set; } + + internal int Latitude { get; private set; } + + internal int Longitude { get; private set; } + + internal void Advance() { + Position += 1; + } + + internal int ExchangeLatitude(ref int latitude) { + var current = Latitude; + Latitude = latitude; + return current; + } + + internal int ExchangeLongitude(ref int longitude) { + var current = Longitude; + Longitude = longitude; + return current; + } + } +} diff --git a/src/PolylineAlgorithm/Polyline.cs b/src/PolylineAlgorithm/Polyline.cs deleted file mode 100644 index 04749496..00000000 --- a/src/PolylineAlgorithm/Polyline.cs +++ /dev/null @@ -1,61 +0,0 @@ -namespace PolylineAlgorithm; - -using System; - -public readonly struct Polyline : IEquatable { - public Polyline() { - Value = Memory.Empty; - } - - public Polyline(string polyline) - : this(polyline.AsMemory()) { - if (string.IsNullOrWhiteSpace(polyline)) { - throw new ArgumentException($"'{nameof(polyline)}' cannot be null or whitespace.", nameof(polyline)); - } - } - - public Polyline(char[] polyline) - : this(polyline.AsMemory()) { - if (polyline is null) { - throw new ArgumentNullException(nameof(polyline)); - } - } - - internal Polyline(ReadOnlyMemory polyline) { - Value = polyline; - } - - public ReadOnlyMemory Value { get; } - - public bool IsEmpty => Value.Length == 0; - - public int Length => Value.Length; - - public char this[int i] { - get => Value.Span[i]; - } - - public override bool Equals(object? obj) { - return obj is Polyline polyline && Equals(polyline); - } - - public bool Equals(Polyline other) { - return Value.Span == other.Value.Span; - } - - public override int GetHashCode() { - return HashCode.Combine(Value); - } - - public static bool operator ==(Polyline left, Polyline right) { - return left.Equals(right); - } - - public static bool operator !=(Polyline left, Polyline right) { - return !(left == right); - } - - public override string ToString() { - return Value.ToString(); - } -} diff --git a/src/PolylineAlgorithm/PolylineDecoder.cs b/src/PolylineAlgorithm/PolylineDecoder.cs new file mode 100644 index 00000000..fd1fd2c4 --- /dev/null +++ b/src/PolylineAlgorithm/PolylineDecoder.cs @@ -0,0 +1,38 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; + +using PolylineAlgorithm.Internal; + +/// +/// A coordinate validator. +public class PolylineDecoder { + + /// + /// Thrown when argument is null -or- empty. + /// Thrown when is not in correct format. + public IEnumerable Decode(ref readonly ReadOnlySpan polyline) { + // Checking null and at least one character + if (polyline.IsEmpty) { + throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullEmptyOrWhitespace, nameof(polyline)); + } + + // Initialize local variables + int capacity = polyline.Length / 9; + var result = new List(capacity); + + PolylineReader reader = new(in polyline); + + // Looping through encoded polyline char array + while (reader.CanRead) { + var coordinate = reader.Read(); + + result.Add(coordinate); + } + + return result; + } +} \ No newline at end of file diff --git a/src/PolylineAlgorithm/PolylineEncoder.cs b/src/PolylineAlgorithm/PolylineEncoder.cs new file mode 100644 index 00000000..9c23cd48 --- /dev/null +++ b/src/PolylineAlgorithm/PolylineEncoder.cs @@ -0,0 +1,52 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; + +using PolylineAlgorithm.Internal; +using System; +using System.Collections.Generic; + +/// +/// Performs polyline algorithm decoding and encoding +/// +public class PolylineEncoder { + /// + /// Encodes coordinates to polyline representation + /// + /// Coordinates to encode + /// Polyline encoded representation + /// If coordinates parameter is null + /// If coordinates parameter is empty + /// If one or more coordinate is out of valid range + public ReadOnlySpan Encode(IEnumerable coordinates) { + if (coordinates is null) { + throw new ArgumentNullException(nameof(coordinates)); + } + + int count = GetCount(ref coordinates); + + if (count == 0) { + throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeEmptyEnumerable, nameof(coordinates)); + } + + // Initializing local variables + int capacity = count * 11; + Span buffer = new char[capacity]; + PolylineWriter writer = new(in buffer); + + // Looping over coordinates and building encoded result + foreach (var coordinate in coordinates) { + writer.Write(in coordinate); + } + + return writer.ToString(); + } + + static int GetCount(ref IEnumerable coordinates) => coordinates switch { + ICollection collection => collection.Count, + _ => coordinates.Count(), + }; +} diff --git a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs deleted file mode 100644 index 95088cba..00000000 --- a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/ContainerBuilderExtensionsTests.cs +++ /dev/null @@ -1,53 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.DependencyInjection.Autofac.Tests; - -using PolylineAlgorithm.Abstraction; -using PolylineAlgorithm.DependencyInjection.Autofac; - -[TestClass] -public class ContainerBuilderExtensionsTests { -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. - private static IContainer Container { get; set; } -#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. - - [ClassInitialize] - public static void ClassInitialize(TestContext context) { - var builder = new ContainerBuilder(); - - builder - .RegisterDefaultPolylineAlgorithm(); - - Container = builder - .Build(); - } - - [TestMethod] - public void Resolve_PolylineEncoder_Test() { - // Arrange - var container = Container; - - // Act - var encoder = container - .Resolve>(); - - // Assert - Assert.IsInstanceOfType>(encoder); - } - - [TestMethod] - public void Resolve_PolylineDecoder_Test() { - // Arrange - var container = Container; - - // Act - var decoder = container - .Resolve>(); - - // Assert - Assert.IsInstanceOfType>(decoder); - } -} \ No newline at end of file diff --git a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalSuppressions.cs b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalSuppressions.cs deleted file mode 100644 index 0b97243b..00000000 --- a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalSuppressions.cs +++ /dev/null @@ -1,8 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -using System.Diagnostics.CodeAnalysis; - -[assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Applies only to production code. Test assemblies are not production code.")] diff --git a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalUsings.cs b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalUsings.cs deleted file mode 100644 index 3464acd3..00000000 --- a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/GlobalUsings.cs +++ /dev/null @@ -1,7 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -global using Autofac; -global using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests.csproj b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests.csproj deleted file mode 100644 index 4b9269c4..00000000 --- a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests.csproj +++ /dev/null @@ -1,42 +0,0 @@ - - - - net9.0 - 13.0 - enable - enable - true - - - - false - true - - - - All - latest - true - false - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - diff --git a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/Properties/AssemblyInfo.cs b/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index aae125e3..00000000 --- a/tests/PolylineAlgorithm.DependencyInjection.Autofac.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] \ No newline at end of file diff --git a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalSuppressions.cs b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalSuppressions.cs deleted file mode 100644 index 0b97243b..00000000 --- a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalSuppressions.cs +++ /dev/null @@ -1,8 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -using System.Diagnostics.CodeAnalysis; - -[assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Applies only to production code. Test assemblies are not production code.")] diff --git a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalUsings.cs b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalUsings.cs deleted file mode 100644 index 1a2cced1..00000000 --- a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/GlobalUsings.cs +++ /dev/null @@ -1,7 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests.csproj b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests.csproj deleted file mode 100644 index 3984b45d..00000000 --- a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests.csproj +++ /dev/null @@ -1,42 +0,0 @@ - - - - net9.0 - 13.0 - enable - enable - true - - - - false - true - - - - All - latest - true - false - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - diff --git a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/Properties/AssemblyInfo.cs b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index aae125e3..00000000 --- a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] \ No newline at end of file diff --git a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs b/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs deleted file mode 100644 index bcfff761..00000000 --- a/tests/PolylineAlgorithm.DependencyInjection.Microsoft.Tests/ServiceCollectionExtensionsTests.cs +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (c) Pete Sramek. All rights reserved. -// Licensed under the MIT License. See LICENSE file in the project root for full license information. -// - -namespace PolylineAlgorithm.DependencyInjection.Microsoft.Tests; - -using PolylineAlgorithm.Abstraction; -using PolylineAlgorithm.DependencyInjection.Microsoft; - -[TestClass] -public class ServiceCollectionExtensionsTests { - private static IServiceCollection Services { get; } = new ServiceCollection().AddDefaultPolylineAlgorithm(); - - [TestMethod] - public void Resolve_PolylineEncoder_Test() { - // Arrange - var provider = Services - .BuildServiceProvider(); - - // Act - var encoder = provider - .GetRequiredService>(); - - // Assert - Assert.IsInstanceOfType>(encoder); - } - - [TestMethod] - public void Resolve_PolylineDecoder_Test() { - // Arrange - var provider = Services - .BuildServiceProvider(); - - // Act - var decoder = provider - .GetRequiredService>(); - - // Assert - Assert.IsInstanceOfType>(decoder); - } -} \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/Defaults.cs b/tests/PolylineAlgorithm.Tests/Defaults.cs index d9594d5b..91d2a4c1 100644 --- a/tests/PolylineAlgorithm.Tests/Defaults.cs +++ b/tests/PolylineAlgorithm.Tests/Defaults.cs @@ -24,21 +24,21 @@ public static class Coordinates { /// /// Defines range of invalid coordinates. Equals to decoded /// - public static readonly IEnumerable Invalid = [ - Coordinate.Create(149.47383, 259.06250), - Coordinate.Create(-158.37407, 225.31250), - Coordinate.Create(152.99363, -220.93750), - Coordinate.Create(-144.49024, -274.37500) - ]; + //public static readonly IEnumerable Invalid = [ + // new(149.47383, 259.06250), + // new(-158.37407, 225.31250), + // new(152.99363, -220.93750), + // new(-144.49024, -274.37500) + //]; /// /// Defines range of valid coordinates. Equals to decoded /// public static readonly IEnumerable Valid = [ - Coordinate.Create(49.47383, 59.06250), - Coordinate.Create(-58.37407, 25.31250), - Coordinate.Create(52.99363, -120.93750), - Coordinate.Create(-44.49024, -174.37500) + new(49.47383, 59.06250), + new(-58.37407, 25.31250), + new(52.99363, -120.93750), + new(-44.49024, -174.37500) ]; } diff --git a/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs b/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs index 1ffd70da..aacd2520 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs +++ b/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs @@ -11,26 +11,22 @@ namespace PolylineAlgorithm.Tests; /// Defines the /// [TestClass] -[TestCategory(nameof(DefaultPolylineDecoder))] +[TestCategory(nameof(PolylineDecoder))] public class PolylineDecoderTest { - private static DefaultPolylineDecoder Decoder { get; } = new DefaultPolylineDecoder(); + public PolylineDecoder Decoder = new PolylineDecoder(); /// /// Method is testing method. Empty [] is passed as parameter. /// Expected result is . /// [TestMethod] - public void Decode_EmptyInput_ThrowsException() { + [ExpectedException(typeof(InvalidOperationException))] + public void Decode_InvalidInput_ThrowsException() { // Arrange - var emptyPolylineCharArray = new Polyline(Defaults.Polyline.Empty); + ReadOnlySpan invalidPolylineCharArray = Defaults.Polyline.Invalid; // Act - void DecodeEmptyPolylineCharArray() { - Decoder.Decode(emptyPolylineCharArray).ToArray(); - } - - // Assert - Assert.ThrowsException(DecodeEmptyPolylineCharArray); + var result = Decoder.Decode(in invalidPolylineCharArray); } /// @@ -40,12 +36,12 @@ void DecodeEmptyPolylineCharArray() { [TestMethod] public void Decode_ValidInput_AreEquivalent() { // Arrange - var validPolylineCharArray = new Polyline(Defaults.Polyline.Valid); + ReadOnlySpan validPolylineCharArray = Defaults.Polyline.Valid; // Act - var result = Decoder.Decode(validPolylineCharArray); + var result = Decoder.Decode(in validPolylineCharArray); // Assert - CollectionAssert.AreEquivalent(Defaults.Coordinates.Valid.ToArray(), result.ToArray()); + CollectionAssert.AreEqual(Defaults.Coordinates.Valid.ToArray(), result.ToArray()); } } diff --git a/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs b/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs index 867a548b..8c833a6f 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs +++ b/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs @@ -8,10 +8,9 @@ namespace PolylineAlgorithm.Tests; /// Defines the /// [TestClass] -[TestCategory(nameof(DefaultPolylineEncoder))] +[TestCategory(nameof(PolylineEncoder))] public class PolylineEncoderTest { - private static DefaultPolylineEncoder Encoder { get; } = new DefaultPolylineEncoder(); - + public PolylineEncoder Encoder = new PolylineEncoder(); /// /// Method is testing method. Empty is passed as parameter. /// Expected result is . @@ -60,6 +59,6 @@ public void Encode_ValidInput_AreEqual() { var result = Encoder.Encode(validCoordinates); // Assert - Assert.AreEqual(new Polyline(Defaults.Polyline.Valid), result); + Assert.AreEqual(Defaults.Polyline.Valid, result.ToString()); } } From c15a0e9bd6f867ea477d115310fb4cf92b703daa Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 00:01:01 +0100 Subject: [PATCH 039/352] added benchmark run action --- .github/workflows/dotnet.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 235f1efd..b653e25b 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -19,10 +19,13 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 9.0.x + dotnet-version: 8.0.x - name: Restore dependencies run: dotnet restore - name: Build run: dotnet build --no-restore - name: Test run: dotnet test --no-build --verbosity normal + - name: Benchmark + working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks + run: dotnet run -c Release \ No newline at end of file From dc98eab29c9d66231b2d94309c6b0309423a0fec Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 00:02:30 +0100 Subject: [PATCH 040/352] updated to dotnet-version: 9.x --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b653e25b..651decab 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -19,7 +19,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 8.0.x + dotnet-version: 9.x - name: Restore dependencies run: dotnet restore - name: Build From e73c054106a4ca5756be4f067c0ca18d2ccf2a37 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 00:05:53 +0100 Subject: [PATCH 041/352] added multiple framewrok version benchmark runs --- .github/workflows/dotnet.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 651decab..66d49b76 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -26,6 +26,18 @@ jobs: run: dotnet build --no-restore - name: Test run: dotnet test --no-build --verbosity normal - - name: Benchmark + - name: Benchmark (.NET 5) working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release \ No newline at end of file + run: dotnet run -c Release --framework net5.0 + - name: Benchmark (.NET 6) + working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks + run: dotnet run -c Release --framework net6.0 + - name: Benchmark (.NET 7) + working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks + run: dotnet run -c Release --framework net7.0 + - name: Benchmark (.NET 8) + working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks + run: dotnet run -c Release --framework net8.0 + - name: Benchmark (.NET 9) + working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks + run: dotnet run -c Release --framework net9.0 \ No newline at end of file From 647ed27926a20f67d091c41a072972460eaac20e Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 00:08:23 +0100 Subject: [PATCH 042/352] added multiple framewrok version setup --- .github/workflows/dotnet.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 66d49b76..91d2f421 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -16,7 +16,23 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Setup .NET + - name: Setup .NET 5 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 5.x + - name: Setup .NET 6 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 6.x + - name: Setup .NET 7 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 7.x + - name: Setup .NET 8 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 8.x + - name: Setup .NET 9 uses: actions/setup-dotnet@v3 with: dotnet-version: 9.x From 9f747104661e0585d67eac9334b787e1cbc90653 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 00:11:29 +0100 Subject: [PATCH 043/352] removed older net version setup and becnhmarks --- .github/workflows/dotnet.yml | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 91d2f421..bdbe71b1 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -16,22 +16,6 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Setup .NET 5 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 5.x - - name: Setup .NET 6 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 6.x - - name: Setup .NET 7 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 7.x - - name: Setup .NET 8 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 8.x - name: Setup .NET 9 uses: actions/setup-dotnet@v3 with: @@ -42,18 +26,6 @@ jobs: run: dotnet build --no-restore - name: Test run: dotnet test --no-build --verbosity normal - - name: Benchmark (.NET 5) - working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --framework net5.0 - - name: Benchmark (.NET 6) - working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --framework net6.0 - - name: Benchmark (.NET 7) - working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --framework net7.0 - - name: Benchmark (.NET 8) - working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --framework net8.0 - name: Benchmark (.NET 9) working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks run: dotnet run -c Release --framework net9.0 \ No newline at end of file From 636ca0a1d036c81c8cc7d83d76a07a61b755c588 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 00:14:20 +0100 Subject: [PATCH 044/352] becnhmarks initialized throught switcher --- benchmarks/PolylineAlgorithm.Benchmarks/Program.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index 87827e06..ea8f13cf 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -8,8 +8,9 @@ namespace PolylineAlgorithm.Benchmarks; using BenchmarkDotNet.Running; internal class Program { - static void Main(string[] _) { - BenchmarkRunner - .Run(); + static void Main(string[] args) { + BenchmarkSwitcher + .FromAssembly(typeof(Program).Assembly) + .Run(args); } } From 6ddecb558757af01168859754d03e231ccf18581 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 00:17:29 +0100 Subject: [PATCH 045/352] updated benchmark run arguments --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index bdbe71b1..d5ff808e 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -28,4 +28,4 @@ jobs: run: dotnet test --no-build --verbosity normal - name: Benchmark (.NET 9) working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --framework net9.0 \ No newline at end of file + run: dotnet run -c Release -- --runtimes net9.0 --filter *PolylineBenchmark* \ No newline at end of file From 6362033789a3e480af3aeb1d1dfdebbe3b5ef4a7 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 00:19:31 +0100 Subject: [PATCH 046/352] added --framework net9.0 to becnhmark command args --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d5ff808e..ec7222b7 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -28,4 +28,4 @@ jobs: run: dotnet test --no-build --verbosity normal - name: Benchmark (.NET 9) working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release -- --runtimes net9.0 --filter *PolylineBenchmark* \ No newline at end of file + run: dotnet run -c Release -- --framework net9.0 --runtimes net9.0 --filter *PolylineBenchmark* \ No newline at end of file From 2d8a6581e62030688aaaa9fe61ab2157dbfd460b Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 00:20:50 +0100 Subject: [PATCH 047/352] updated benchmark command --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index ec7222b7..8869ed03 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -28,4 +28,4 @@ jobs: run: dotnet test --no-build --verbosity normal - name: Benchmark (.NET 9) working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release -- --framework net9.0 --runtimes net9.0 --filter *PolylineBenchmark* \ No newline at end of file + run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter *PolylineBenchmark* \ No newline at end of file From c5c83c7cfdb21b8bf6bd72ab2361969b13fac6ed Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 00:23:27 +0100 Subject: [PATCH 048/352] updated becnhmark filter --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 8869ed03..36353b18 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -28,4 +28,4 @@ jobs: run: dotnet test --no-build --verbosity normal - name: Benchmark (.NET 9) working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter *PolylineBenchmark* \ No newline at end of file + run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter * \ No newline at end of file From 72944e526eddcd64cf3003625edeb0100b74b921 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 00:25:09 +0100 Subject: [PATCH 049/352] removed becnhmark filter arg --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 36353b18..de7e58eb 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -28,4 +28,4 @@ jobs: run: dotnet test --no-build --verbosity normal - name: Benchmark (.NET 9) working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter * \ No newline at end of file + run: dotnet run -c Release --framework net9.0 --runtimes net9.0 \ No newline at end of file From c18db1a45dd1941bbd1b5dc3c4fedea7096a9010 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 00:27:29 +0100 Subject: [PATCH 050/352] added filter args --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index de7e58eb..c0d27d07 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -28,4 +28,4 @@ jobs: run: dotnet test --no-build --verbosity normal - name: Benchmark (.NET 9) working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --framework net9.0 --runtimes net9.0 \ No newline at end of file + run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter '*PolylineBenchmark*' \ No newline at end of file From dd7c5e70aac569353abe3aece7eec2f58ad2cb0e Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 00:29:55 +0100 Subject: [PATCH 051/352] removed predefined runtimes --- .../PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs index 4f273324..c7ed7d93 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs @@ -7,7 +7,6 @@ namespace PolylineAlgorithm.Benchmarks; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; -using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; using Cloudikka.PolylineAlgorithm.Encoding; using PolylineAlgorithm; @@ -16,11 +15,6 @@ namespace PolylineAlgorithm.Benchmarks; [RankColumn] [MemoryDiagnoser] -[SimpleJob(RuntimeMoniker.Net50, baseline: true)] -[SimpleJob(RuntimeMoniker.Net60)] -[SimpleJob(RuntimeMoniker.Net70)] -[SimpleJob(RuntimeMoniker.Net80)] -[SimpleJob(RuntimeMoniker.Net90)] [Orderer(SummaryOrderPolicy.Default)] public class PolylineBenchmark { private readonly Consumer _consumer = new(); From 0d392fbf889c8cf0282f807aa45d89136db7f327 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 14:41:19 +0100 Subject: [PATCH 052/352] removed framewrok version from title --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c0d27d07..f7450506 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -26,6 +26,6 @@ jobs: run: dotnet build --no-restore - name: Test run: dotnet test --no-build --verbosity normal - - name: Benchmark (.NET 9) + - name: Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter '*PolylineBenchmark*' \ No newline at end of file From bd607ecdb5eb0a07c18abb585fc25fc131634730 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 14:41:37 +0100 Subject: [PATCH 053/352] reorganized benchmark classes --- .../DecodeBenchmark.cs | 45 +++++++++++++++++++ ...olylineBenchmark.cs => EncodeBenchmark.cs} | 29 +----------- 2 files changed, 46 insertions(+), 28 deletions(-) create mode 100644 benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs rename benchmarks/PolylineAlgorithm.Benchmarks/{PolylineBenchmark.cs => EncodeBenchmark.cs} (77%) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs new file mode 100644 index 00000000..576b6b33 --- /dev/null +++ b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs @@ -0,0 +1,45 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Benchmarks; + +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Order; +using Cloudikka.PolylineAlgorithm.Encoding; +using PolylineAlgorithm; +using PolylinerNet; +using System.Collections.Generic; + +[RankColumn] +[MemoryDiagnoser] +[Orderer(SummaryOrderPolicy.Default)] +public class DecodeBenchmark { + private readonly Consumer _consumer = new(); + public static string String_Polyline { get; } = "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"; + public static ReadOnlyMemory Memory_Polyline { get; } = String_Polyline.AsMemory(); + + + [Benchmark] + public void PolylineDecoder_Decode() { + ReadOnlySpan polyline = Memory_Polyline.Span; + var decoder = new PolylineDecoder(); + decoder.Decode(in polyline).Consume(_consumer); + } + + [Benchmark] + public void Polyliner_Decode() { + string polyline = String_Polyline; + var polyliner = new Polyliner(); + polyliner.Decode(polyline).Consume(_consumer); + } + + [Benchmark] + public void Cloudikka_PolylineEncoding_Decode() { + string polyline = String_Polyline; + var polyliner = new PolylineEncoding(); + polyliner.Decode(polyline).Consume(_consumer); + } +} diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs similarity index 77% rename from benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs rename to benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs index c7ed7d93..5d70b9c6 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/PolylineBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs @@ -16,39 +16,12 @@ namespace PolylineAlgorithm.Benchmarks; [RankColumn] [MemoryDiagnoser] [Orderer(SummaryOrderPolicy.Default)] -public class PolylineBenchmark { - private readonly Consumer _consumer = new(); - public static string String_Polyline { get; } = "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"; - public static ReadOnlyMemory Memory_Polyline { get; } = String_Polyline.AsMemory(); - +public class EncodeBenchmark { public static IEnumerable PolylineAlgorithm_Coordinates { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; public static List PolylinerNet_PolylinePoint { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; public static IEnumerable<(double, double)> Cloudikka_PolylineEncoding_Tuple { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; - - [Benchmark] - public void PolylineDecoder_Decode() { - ReadOnlySpan polyline = Memory_Polyline.Span; - var decoder = new PolylineDecoder(); - decoder.Decode(in polyline).Consume(_consumer); - } - - [Benchmark] - public void Polyliner_Decode() { - string polyline = String_Polyline; - var polyliner = new Polyliner(); - polyliner.Decode(polyline).Consume(_consumer); - } - - [Benchmark] - public void Cloudikka_PolylineEncoding_Decode() { - string polyline = String_Polyline; - var polyliner = new PolylineEncoding(); - polyliner.Decode(polyline).Consume(_consumer); - } - - [Benchmark] public ReadOnlySpan PolylineEncoder_Encode() { var encoder = new PolylineEncoder(); From 52ebf31fccd4eae53eeba618185b7e3279f1a7cd Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 14:43:53 +0100 Subject: [PATCH 054/352] fixed benchmark filter --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index f7450506..291ecb12 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -28,4 +28,4 @@ jobs: run: dotnet test --no-build --verbosity normal - name: Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter '*PolylineBenchmark*' \ No newline at end of file + run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter '*Benchmark*' \ No newline at end of file From 5fd20ad5beba03f45c4051b6e057e4a41ccb0bdc Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 14:50:02 +0100 Subject: [PATCH 055/352] added baseline attribute --- benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs | 2 +- benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs index 576b6b33..06bdf75d 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs @@ -22,7 +22,7 @@ public class DecodeBenchmark { public static ReadOnlyMemory Memory_Polyline { get; } = String_Polyline.AsMemory(); - [Benchmark] + [Benchmark(Baseline = true)] public void PolylineDecoder_Decode() { ReadOnlySpan polyline = Memory_Polyline.Span; var decoder = new PolylineDecoder(); diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs index 5d70b9c6..4fc2cf6a 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs @@ -22,7 +22,7 @@ public class EncodeBenchmark { public static IEnumerable<(double, double)> Cloudikka_PolylineEncoding_Tuple { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; - [Benchmark] + [Benchmark(Baseline = true)] public ReadOnlySpan PolylineEncoder_Encode() { var encoder = new PolylineEncoder(); return encoder.Encode(PolylineAlgorithm_Coordinates); From cc63e8eb2e705f325aad830c7c554cb9ab14813b Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 14:50:55 +0100 Subject: [PATCH 056/352] split benchmark to decode and encode actions --- .github/workflows/dotnet.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 291ecb12..29fc62bd 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -26,6 +26,9 @@ jobs: run: dotnet build --no-restore - name: Test run: dotnet test --no-build --verbosity normal - - name: Benchmark + - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter '*Benchmark*' \ No newline at end of file + run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter '*DecodeBenchmark*' + - name: Encode Benchmark + working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks + run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter '*EncodeBenchmark*' \ No newline at end of file From 796c1908515554dc215e674c43e10a90ddd3f9d0 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 15:03:30 +0100 Subject: [PATCH 057/352] split job to build and benchmark, added OS matrix and concurrent execution to benchmark job --- .github/workflows/dotnet.yml | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 29fc62bd..2cea1c50 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -11,7 +11,6 @@ on: jobs: build: - runs-on: ubuntu-latest steps: @@ -20,7 +19,7 @@ jobs: uses: actions/setup-dotnet@v3 with: dotnet-version: 9.x - - name: Restore dependencies + - name: Restore run: dotnet restore - name: Build run: dotnet build --no-restore @@ -31,4 +30,28 @@ jobs: run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter '*DecodeBenchmark*' - name: Encode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter '*EncodeBenchmark*' \ No newline at end of file + run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter '*EncodeBenchmark*' + benchmark: + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + runs-on: $ + + concurrency: + group: becnhmark-group + cancel-in-progress: true + + steps: + - uses: actions/checkout@v3 + - name: Setup .NET 9 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 9.x + - name: Restore + run: dotnet restore + - name: Decode Benchmark + working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks + run: dotnet run -c Release --no-restore --framework net9.0 --runtimes net9.0 --filter '*DecodeBenchmark*' + - name: Encode Benchmark + working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks + run: dotnet run -c Release --no-restore --framework net9.0 --runtimes net9.0 --filter '*EncodeBenchmark*' \ No newline at end of file From 8bdd8249c842c54eaabeea987b0b4f14692b7678 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 15:06:49 +0100 Subject: [PATCH 058/352] added dependency benchmark on build job --- .github/workflows/dotnet.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 2cea1c50..8ccf367c 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -32,6 +32,8 @@ jobs: working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter '*EncodeBenchmark*' benchmark: + needs: [build] + strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] From 28787d12cad2d2a50fdfaa230629d33bd0617253 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 15:07:06 +0100 Subject: [PATCH 059/352] removed restore step from benchmark job --- .github/workflows/dotnet.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 8ccf367c..73823064 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -49,8 +49,6 @@ jobs: uses: actions/setup-dotnet@v3 with: dotnet-version: 9.x - - name: Restore - run: dotnet restore - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks run: dotnet run -c Release --no-restore --framework net9.0 --runtimes net9.0 --filter '*DecodeBenchmark*' From caf8ae9fbc61b67d88382a5c8ef2f2d83fd93d6d Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 16:42:16 +0100 Subject: [PATCH 060/352] updated runs-on to reffer to matrix.os --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 73823064..5e5f8e95 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -37,7 +37,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - runs-on: $ + runs-on: ${{ matrix.os }} concurrency: group: becnhmark-group From 92b2c2dcb40a4b914c25fee43cfe9690a6311652 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 16:44:38 +0100 Subject: [PATCH 061/352] removed benchmarks from build job --- .github/workflows/dotnet.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 5e5f8e95..6504ac08 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -25,12 +25,6 @@ jobs: run: dotnet build --no-restore - name: Test run: dotnet test --no-build --verbosity normal - - name: Decode Benchmark - working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter '*DecodeBenchmark*' - - name: Encode Benchmark - working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --framework net9.0 --runtimes net9.0 --filter '*EncodeBenchmark*' benchmark: needs: [build] From c7ea34c670bdb0cf98e6b60946fc438440a00936 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 16:46:22 +0100 Subject: [PATCH 062/352] separatet test job --- .github/workflows/dotnet.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 6504ac08..fa7bf656 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -25,16 +25,32 @@ jobs: run: dotnet build --no-restore - name: Test run: dotnet test --no-build --verbosity normal + + test: + needs: [build] + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Setup .NET 9 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 9.x + - name: Test + run: dotnet test --no-build --verbosity normal + benchmark: needs: [build] strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{ matrix.os }} concurrency: - group: becnhmark-group + group: benchmark-group cancel-in-progress: true steps: From 8102fdd4cfefbaaa1da5f17cd12a0d3f17d64310 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 16:58:54 +0100 Subject: [PATCH 063/352] upload download artifact --- .github/workflows/dotnet.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index fa7bf656..5acf1aa3 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -23,8 +23,11 @@ jobs: run: dotnet restore - name: Build run: dotnet build --no-restore - - name: Test - run: dotnet test --no-build --verbosity normal + - name: Upload + uses: actions/upload-artifact@v4 + with: + name: build + path: build test: needs: [build] @@ -37,6 +40,11 @@ jobs: uses: actions/setup-dotnet@v3 with: dotnet-version: 9.x + - uses: actions/download-artifact@v4 + - name: Display structure of downloaded files + with: + path: build + run: ls -R - name: Test run: dotnet test --no-build --verbosity normal From ddb8c6d82a126ca05bc185c5a19e30182fb667fd Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 17:05:23 +0100 Subject: [PATCH 064/352] updated --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 5acf1aa3..32695bfa 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -41,10 +41,10 @@ jobs: with: dotnet-version: 9.x - uses: actions/download-artifact@v4 - - name: Display structure of downloaded files + name: Display structure of downloaded files with: path: build - run: ls -R + run: ls -R - name: Test run: dotnet test --no-build --verbosity normal From e56c9423bb83dba2a57e364c9d87bd5362c8da9e Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 17:07:09 +0100 Subject: [PATCH 065/352] changed path to . --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 32695bfa..4169b0d6 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -27,7 +27,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: build - path: build + path: . test: needs: [build] From c4c41886a714f58dbf9433c79b92ec53058998c1 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 17:11:55 +0100 Subject: [PATCH 066/352] updated artifact download --- .github/workflows/dotnet.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 4169b0d6..902fcdca 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -41,10 +41,12 @@ jobs: with: dotnet-version: 9.x - uses: actions/download-artifact@v4 - name: Display structure of downloaded files with: - path: build - run: ls -R + name: build + path: . + merge-multiple: true + - name: Display structure of downloaded files + run: ls -R path/to/artifacts - name: Test run: dotnet test --no-build --verbosity normal @@ -67,6 +69,11 @@ jobs: uses: actions/setup-dotnet@v3 with: dotnet-version: 9.x + - uses: actions/download-artifact@v4 + with: + name: build + path: . + merge-multiple: true - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks run: dotnet run -c Release --no-restore --framework net9.0 --runtimes net9.0 --filter '*DecodeBenchmark*' From 860689152d161b503d1ba3b37e2dfaff54f4b2c6 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 17:14:57 +0100 Subject: [PATCH 067/352] removed incorrect path --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 902fcdca..f15c8a37 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -46,7 +46,7 @@ jobs: path: . merge-multiple: true - name: Display structure of downloaded files - run: ls -R path/to/artifacts + run: ls -R . - name: Test run: dotnet test --no-build --verbosity normal From 109093491dc54a4460850037066a09ba5c997c58 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 17:20:40 +0100 Subject: [PATCH 068/352] added path to build files --- .github/workflows/dotnet.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index f15c8a37..042f6c84 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -27,7 +27,9 @@ jobs: uses: actions/upload-artifact@v4 with: name: build - path: . + path: | + **/bin/* + **/obj/* test: needs: [build] From 6b6a0677fcf9721be1726ad2dc605bf3ab2c6501 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 17:25:39 +0100 Subject: [PATCH 069/352] no build no restore --- .github/workflows/dotnet.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 042f6c84..0df4c638 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -50,7 +50,7 @@ jobs: - name: Display structure of downloaded files run: ls -R . - name: Test - run: dotnet test --no-build --verbosity normal + run: dotnet test --no-restore --no-build --verbosity normal benchmark: needs: [build] @@ -78,7 +78,7 @@ jobs: merge-multiple: true - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --no-restore --framework net9.0 --runtimes net9.0 --filter '*DecodeBenchmark*' + run: dotnet run -c Release --no-restore --no-build --framework net9.0 --runtimes net9.0 --filter '*DecodeBenchmark*' - name: Encode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --no-restore --framework net9.0 --runtimes net9.0 --filter '*EncodeBenchmark*' \ No newline at end of file + run: dotnet run -c Release --no-restore --no-build --framework net9.0 --runtimes net9.0 --filter '*EncodeBenchmark*' \ No newline at end of file From 98c690216acee3b7422ef85718f3b609cded5a74 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 17:30:17 +0100 Subject: [PATCH 070/352] removed concurrent --- .github/workflows/dotnet.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 0df4c638..b7d3c494 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -61,10 +61,6 @@ jobs: runs-on: ${{ matrix.os }} - concurrency: - group: benchmark-group - cancel-in-progress: true - steps: - uses: actions/checkout@v3 - name: Setup .NET 9 From e55548834c040c3720593dcedd68abfc3ed74af2 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 17:33:58 +0100 Subject: [PATCH 071/352] disabled CI --- .github/workflows/dotnet.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b7d3c494..9993fefd 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -58,15 +58,16 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] + netversion: [5, 6, 7, 8, 9] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 - - name: Setup .NET 9 + - name: Setup .NET ${{ matrix.netversion }} uses: actions/setup-dotnet@v3 with: - dotnet-version: 9.x + dotnet-version: ${{ matrix.netversion }}.x - uses: actions/download-artifact@v4 with: name: build @@ -74,7 +75,7 @@ jobs: merge-multiple: true - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --no-restore --no-build --framework net9.0 --runtimes net9.0 --filter '*DecodeBenchmark*' + run: CI=false dotnet run -c Release --no-restore --no-build --framework net${{ matrix.netversion }}.0 --runtimes net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' - name: Encode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --no-restore --no-build --framework net9.0 --runtimes net9.0 --filter '*EncodeBenchmark*' \ No newline at end of file + run: CI=false dotnet run -c Release --no-restore --no-build --framework net${{ matrix.netversion }}.0 --runtimes net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file From 246d7041eb13446ca4fed9b7175caf44483d90b8 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 17:41:22 +0100 Subject: [PATCH 072/352] added libssl conditional step for net 5 --- .github/workflows/dotnet.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 9993fefd..00254a5a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -64,6 +64,9 @@ jobs: steps: - uses: actions/checkout@v3 + - name: Fix libssl + run: sudo dpkg -i libssl1.0.0_1.0.2n-1ubuntu5_amd64.deb + if: ${{ matrix.netversion }} == 5 - name: Setup .NET ${{ matrix.netversion }} uses: actions/setup-dotnet@v3 with: From 91103919274b76186d2c1799b774b4c2bb6ad089 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 17:47:25 +0100 Subject: [PATCH 073/352] updated ssl command --- .github/workflows/dotnet.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 00254a5a..c60a15e9 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -65,8 +65,9 @@ jobs: steps: - uses: actions/checkout@v3 - name: Fix libssl - run: sudo dpkg -i libssl1.0.0_1.0.2n-1ubuntu5_amd64.deb - if: ${{ matrix.netversion }} == 5 + run: | + wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb + sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb - name: Setup .NET ${{ matrix.netversion }} uses: actions/setup-dotnet@v3 with: From 751c7aeba50f40349f22eb44ee8a78c9c73214e4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 17:52:55 +0100 Subject: [PATCH 074/352] updated if statement --- .github/workflows/dotnet.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c60a15e9..3f6c2c13 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -64,14 +64,15 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Fix libssl - run: | - wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb - sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb - name: Setup .NET ${{ matrix.netversion }} uses: actions/setup-dotnet@v3 with: dotnet-version: ${{ matrix.netversion }}.x + - name: Fix libssl + if: ${{ matrix.netversion == 5 && matrix.os == 'ubuntu-latest' }} + run: | + wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb + sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb - uses: actions/download-artifact@v4 with: name: build From 21bde88077bc44c189fd694109df4150913d8136 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 17:56:05 +0100 Subject: [PATCH 075/352] removed directory listing in console --- .github/workflows/dotnet.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 3f6c2c13..5fe81922 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -47,8 +47,6 @@ jobs: name: build path: . merge-multiple: true - - name: Display structure of downloaded files - run: ls -R . - name: Test run: dotnet test --no-restore --no-build --verbosity normal @@ -80,7 +78,7 @@ jobs: merge-multiple: true - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: CI=false dotnet run -c Release --no-restore --no-build --framework net${{ matrix.netversion }}.0 --runtimes net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' + run: dotnet run -c Release --no-restore --no-build --framework net${{ matrix.netversion }}.0 --runtimes net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' - name: Encode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: CI=false dotnet run -c Release --no-restore --no-build --framework net${{ matrix.netversion }}.0 --runtimes net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file + run: dotnet run -c Release --no-restore --no-build --framework net${{ matrix.netversion }}.0 --runtimes net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file From a26463e8534c278296971c56a053ca60454bce93 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 17:59:59 +0100 Subject: [PATCH 076/352] updated build job to run multiple buiold for net framewrok --- .github/workflows/dotnet.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 5fe81922..a196a9aa 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,16 +13,20 @@ jobs: build: runs-on: ubuntu-latest + strategy: + matrix: + netversion: [5, 6, 7, 8, 9] + steps: - uses: actions/checkout@v3 - name: Setup .NET 9 uses: actions/setup-dotnet@v3 with: - dotnet-version: 9.x + dotnet-version: ${{ matrix.netversion }}.x - name: Restore run: dotnet restore - name: Build - run: dotnet build --no-restore + run: dotnet build --no-restore - name: Upload uses: actions/upload-artifact@v4 with: From d74b058971e5492ddf67ade4f991e218d0b6d9c7 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:01:55 +0100 Subject: [PATCH 077/352] removed not supported ner versions --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index a196a9aa..a01e58c3 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: - netversion: [5, 6, 7, 8, 9] + netversion: [7, 8, 9] steps: - uses: actions/checkout@v3 @@ -60,7 +60,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - netversion: [5, 6, 7, 8, 9] + netversion: [7, 8, 9] runs-on: ${{ matrix.os }} From 34e685ff46c0a70b770fe8329d853b5b5d156d4a Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:03:46 +0100 Subject: [PATCH 078/352] wait what? --- .github/workflows/dotnet.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index a01e58c3..b6c24e16 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -11,6 +11,7 @@ on: jobs: build: + name: Build with .NET ${{ matrix.netversion }} runs-on: ubuntu-latest strategy: @@ -19,7 +20,7 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Setup .NET 9 + - name: Setup .NET ${{ matrix.netversion }} uses: actions/setup-dotnet@v3 with: dotnet-version: ${{ matrix.netversion }}.x From 5fdd857dde3b189b20978fe423bc3f97712de385 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:09:56 +0100 Subject: [PATCH 079/352] added --framework net${{ matrix.netversion }}.0 --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b6c24e16..4832269a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -27,7 +27,7 @@ jobs: - name: Restore run: dotnet restore - name: Build - run: dotnet build --no-restore + run: dotnet build --no-restore --framework net${{ matrix.netversion }}.0 - name: Upload uses: actions/upload-artifact@v4 with: From 662de3029f798802e359d691f63ca8e7f315c801 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:12:18 +0100 Subject: [PATCH 080/352] added --framework net${{ matrix.netversion }}.0 --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 4832269a..4281b286 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -25,7 +25,7 @@ jobs: with: dotnet-version: ${{ matrix.netversion }}.x - name: Restore - run: dotnet restore + run: dotnet restore --framework net${{ matrix.netversion }}.0 - name: Build run: dotnet build --no-restore --framework net${{ matrix.netversion }}.0 - name: Upload From b90bd07b17f9db10eabd43c21b6432deef701a0d Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:14:53 +0100 Subject: [PATCH 081/352] test --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 4281b286..4fa82670 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -25,9 +25,9 @@ jobs: with: dotnet-version: ${{ matrix.netversion }}.x - name: Restore - run: dotnet restore --framework net${{ matrix.netversion }}.0 + run: dotnet restore - name: Build - run: dotnet build --no-restore --framework net${{ matrix.netversion }}.0 + run: dotnet build --no-restore --framework net${{ matrix.netversion }}.0 --runtimes net${{ matrix.netversion }}.0 - name: Upload uses: actions/upload-artifact@v4 with: From 7fbdf0712be810e60779be97d23c28e9b2b99417 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:17:58 +0100 Subject: [PATCH 082/352] test --- .github/workflows/dotnet.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 4fa82670..6265063f 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,20 +14,16 @@ jobs: name: Build with .NET ${{ matrix.netversion }} runs-on: ubuntu-latest - strategy: - matrix: - netversion: [7, 8, 9] - steps: - uses: actions/checkout@v3 - - name: Setup .NET ${{ matrix.netversion }} + - name: Setup .NET 9 uses: actions/setup-dotnet@v3 with: - dotnet-version: ${{ matrix.netversion }}.x + dotnet-version: 9.x - name: Restore run: dotnet restore - name: Build - run: dotnet build --no-restore --framework net${{ matrix.netversion }}.0 --runtimes net${{ matrix.netversion }}.0 + run: dotnet build --no-restore - name: Upload uses: actions/upload-artifact@v4 with: From 32ae070c266fee0e9b4cf28e36b398e135bd8411 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:18:35 +0100 Subject: [PATCH 083/352] removed runtimes --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 6265063f..9a51cb0c 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -79,7 +79,7 @@ jobs: merge-multiple: true - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --no-restore --no-build --framework net${{ matrix.netversion }}.0 --runtimes net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' + run: dotnet run -c Release --no-restore --no-build --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' - name: Encode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --no-restore --no-build --framework net${{ matrix.netversion }}.0 --runtimes net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file + run: dotnet run -c Release --no-restore --no-build --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file From 2d7843ac07587a75a77f3ee8846a2c370d439ee8 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:19:27 +0100 Subject: [PATCH 084/352] test --- .github/workflows/dotnet.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 9a51cb0c..3f97f5cc 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -33,6 +33,7 @@ jobs: **/obj/* test: + name: Test with MsTest needs: [build] runs-on: ubuntu-latest From 59a7335e5a4c79f59fce969e7b471b2735775a82 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:23:42 +0100 Subject: [PATCH 085/352] updated --- .github/workflows/dotnet.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 3f97f5cc..0f71aa10 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -12,18 +12,23 @@ on: jobs: build: name: Build with .NET ${{ matrix.netversion }} + + strategy: + matrix: + netversion: [7, 8, 9] + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Setup .NET 9 + - name: Setup .NET ${{ matrix.netversion }} uses: actions/setup-dotnet@v3 with: - dotnet-version: 9.x + dotnet-version: ${{ matrix.netversion }}.x - name: Restore run: dotnet restore - name: Build - run: dotnet build --no-restore + run: dotnet build --no-restore --framework ${{ matrix.netversion }}.0 - name: Upload uses: actions/upload-artifact@v4 with: From d7dc6d39b96aca0d31877472077c56435340ba60 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:24:58 +0100 Subject: [PATCH 086/352] fix --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 0f71aa10..2ca762a4 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -24,7 +24,7 @@ jobs: - name: Setup .NET ${{ matrix.netversion }} uses: actions/setup-dotnet@v3 with: - dotnet-version: ${{ matrix.netversion }}.x + dotnet-version: 9.x - name: Restore run: dotnet restore - name: Build From 4c96b9837d91588554e6e863a8d0e28bd0c2a9da Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:26:43 +0100 Subject: [PATCH 087/352] updated framewroks --- tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index ef3223fa..f8674a6b 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -1,7 +1,7 @@  - net9.0 + net5.0;net6.0;net7.0;net8.0;net9.0 13.0 enable enable From a3fda60ea7b8faff935c5e84f44247bfcb5ecb52 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:28:18 +0100 Subject: [PATCH 088/352] fix --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 2ca762a4..70c7da46 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -28,7 +28,7 @@ jobs: - name: Restore run: dotnet restore - name: Build - run: dotnet build --no-restore --framework ${{ matrix.netversion }}.0 + run: dotnet build --no-restore --framework net${{ matrix.netversion }}.0 - name: Upload uses: actions/upload-artifact@v4 with: From 4904769d17bf88f7e356a4cf1bfbe344db292c60 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:31:25 +0100 Subject: [PATCH 089/352] wait what? --- .github/workflows/dotnet.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 70c7da46..3f1cfcd1 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,22 +13,18 @@ jobs: build: name: Build with .NET ${{ matrix.netversion }} - strategy: - matrix: - netversion: [7, 8, 9] - runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Setup .NET ${{ matrix.netversion }} + - name: Setup .NET 9 uses: actions/setup-dotnet@v3 with: dotnet-version: 9.x - name: Restore run: dotnet restore - name: Build - run: dotnet build --no-restore --framework net${{ matrix.netversion }}.0 + run: dotnet build --no-restore - name: Upload uses: actions/upload-artifact@v4 with: From e05e77a1819b8c42d9b318fe8eb30125a2dc56d4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:35:23 +0100 Subject: [PATCH 090/352] updated test project csproj --- tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index f8674a6b..ef3223fa 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -1,7 +1,7 @@  - net5.0;net6.0;net7.0;net8.0;net9.0 + net9.0 13.0 enable enable From 6bc4e73e9f052829c5a4e238ef1c1b5ef4dbf92a Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:42:09 +0100 Subject: [PATCH 091/352] fix --- .github/workflows/dotnet.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 3f1cfcd1..be9da0f6 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -24,7 +24,7 @@ jobs: - name: Restore run: dotnet restore - name: Build - run: dotnet build --no-restore + run: dotnet build --no-restore --configuration Release - name: Upload uses: actions/upload-artifact@v4 with: @@ -51,9 +51,10 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --verbosity normal + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal benchmark: + name: Benchmark with .NET net${{ matrix.netversion }} on ${{ matrix.os }} needs: [build] strategy: @@ -81,7 +82,7 @@ jobs: merge-multiple: true - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --no-restore --no-build --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' + run: dotnet run -c Release --no-restore --no-build --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' - name: Encode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --no-restore --no-build --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file + run: dotnet run -c Release --no-restore --no-build --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file From edf624bacf763e64425eaa30b42d7b4ff28c4f19 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:44:04 +0100 Subject: [PATCH 092/352] fix --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index be9da0f6..2928da05 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -82,7 +82,7 @@ jobs: merge-multiple: true - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --no-restore --no-build --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' + run: dotnet run --no-restore --no-build --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' - name: Encode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release --no-restore --no-build --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file + run: dotnet run --no-restore --no-build --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file From 546351048a55269a9dca638c82322892e698056e Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:46:35 +0100 Subject: [PATCH 093/352] whaaat? --- .github/workflows/dotnet.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 2928da05..bf3403bf 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -81,8 +81,6 @@ jobs: path: . merge-multiple: true - name: Decode Benchmark - working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --no-restore --no-build --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' + run: dotnet run --no-restore --no-build --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' - name: Encode Benchmark - working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --no-restore --no-build --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file + run: dotnet run --no-restore --no-build --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file From 70df963d40eef86d69d0bf3bf3db6ede94acc75f Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:49:18 +0100 Subject: [PATCH 094/352] refixed --- .github/workflows/dotnet.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index bf3403bf..874b92d8 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -81,6 +81,8 @@ jobs: path: . merge-multiple: true - name: Decode Benchmark + working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks run: dotnet run --no-restore --no-build --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' - name: Encode Benchmark + working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks run: dotnet run --no-restore --no-build --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file From e2e788041cb751b1f8fd78a5519b8d27cba08733 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 18:56:59 +0100 Subject: [PATCH 095/352] hwat is this --- .github/workflows/dotnet.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 874b92d8..326f8f56 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -11,13 +11,13 @@ on: jobs: build: - name: Build with .NET ${{ matrix.netversion }} + name: Build with .NET 9 runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Setup .NET 9 + - name: Install .NET 9 uses: actions/setup-dotnet@v3 with: dotnet-version: 9.x @@ -51,10 +51,10 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal benchmark: - name: Benchmark with .NET net${{ matrix.netversion }} on ${{ matrix.os }} + name: Benchmark with .NET ${{ matrix.netversion }}.0 on ${{ matrix.os }} needs: [build] strategy: @@ -82,7 +82,7 @@ jobs: merge-multiple: true - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --no-restore --no-build --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' + run: dotnet run --no-restore --no-build --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' - name: Encode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --no-restore --no-build --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file + run: dotnet run --no-restore --no-build --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file From 2117c0c87f17ca2037a8a8d044f315984268c721 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 19:05:42 +0100 Subject: [PATCH 096/352] added concurrency --- .github/workflows/dotnet.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 326f8f56..1044e3a5 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -62,6 +62,9 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] netversion: [7, 8, 9] + concurrency: + group: benchmark + runs-on: ${{ matrix.os }} steps: From 86fd540d38415a02f3ee34d1a7f85188d7c204a4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 19:07:58 +0100 Subject: [PATCH 097/352] removed no build --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 1044e3a5..b7c1afcd 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -85,7 +85,7 @@ jobs: merge-multiple: true - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --no-restore --no-build --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' + run: dotnet run --no-restore --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' - name: Encode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --no-restore --no-build --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file + run: dotnet run --no-restore --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file From e9d15edc00c7d42dbc9e0479c6ef8a6ea2f36834 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 19:12:42 +0100 Subject: [PATCH 098/352] fix --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b7c1afcd..161ba065 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -85,7 +85,7 @@ jobs: merge-multiple: true - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --no-restore --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' + run: dotnet run --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' - name: Encode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --no-restore --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file + run: dotnet run --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file From ea2cb8a98c84ce3430fda49c51c01b4dbdde55bf Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 19:14:38 +0100 Subject: [PATCH 099/352] removed concurrency --- .github/workflows/dotnet.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 161ba065..45636121 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -62,9 +62,6 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] netversion: [7, 8, 9] - concurrency: - group: benchmark - runs-on: ${{ matrix.os }} steps: From d0b7368b6703b5835adcd2da3fc475a2d01488f4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 19:18:20 +0100 Subject: [PATCH 100/352] returned --- .github/workflows/dotnet.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 45636121..161ba065 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -62,6 +62,9 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] netversion: [7, 8, 9] + concurrency: + group: benchmark + runs-on: ${{ matrix.os }} steps: From 2a3d8618f514e09f976212bd4f8c8e4f78c6b0b0 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 19:33:02 +0100 Subject: [PATCH 101/352] cancel-in-progress: false --- .github/workflows/dotnet.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 161ba065..a586ad41 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -64,6 +64,7 @@ jobs: concurrency: group: benchmark + cancel-in-progress: false runs-on: ${{ matrix.os }} From 3b4b275f9dd998a5f278d0b82ac2c38b927b4cc4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 19:49:06 +0100 Subject: [PATCH 102/352] refacroteed benchmarks --- .github/workflows/dotnet.yml | 22 ++++++++++--------- .../DecodeBenchmark.cs | 5 ++++- .../EncodeBenchmark.cs | 4 ++++ .../PolylineAlgorithm.Benchmarks/Program.cs | 7 +++--- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index a586ad41..3af4b90a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -60,7 +60,6 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - netversion: [7, 8, 9] concurrency: group: benchmark @@ -70,15 +69,18 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Setup .NET ${{ matrix.netversion }} + - name: Setup .NET 7 uses: actions/setup-dotnet@v3 with: - dotnet-version: ${{ matrix.netversion }}.x - - name: Fix libssl - if: ${{ matrix.netversion == 5 && matrix.os == 'ubuntu-latest' }} - run: | - wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb - sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb + dotnet-version: 7.x + - name: Setup .NET 8 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 8.x + - name: Setup .NET 9 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 9.x - uses: actions/download-artifact@v4 with: name: build @@ -86,7 +88,7 @@ jobs: merge-multiple: true - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' + run: dotnet run --configuration Release - name: Encode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file + run: dotnet run --configuration Release \ No newline at end of file diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs index 06bdf75d..7c2251db 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs @@ -7,14 +7,17 @@ namespace PolylineAlgorithm.Benchmarks; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; using Cloudikka.PolylineAlgorithm.Encoding; using PolylineAlgorithm; using PolylinerNet; -using System.Collections.Generic; [RankColumn] [MemoryDiagnoser] +[SimpleJob(RuntimeMoniker.Net70, baseline: true)] +[SimpleJob(RuntimeMoniker.Net80)] +[SimpleJob(RuntimeMoniker.Net90)] [Orderer(SummaryOrderPolicy.Default)] public class DecodeBenchmark { private readonly Consumer _consumer = new(); diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs index 4fc2cf6a..b995e56b 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs @@ -7,6 +7,7 @@ namespace PolylineAlgorithm.Benchmarks; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; using Cloudikka.PolylineAlgorithm.Encoding; using PolylineAlgorithm; @@ -15,6 +16,9 @@ namespace PolylineAlgorithm.Benchmarks; [RankColumn] [MemoryDiagnoser] +[SimpleJob(RuntimeMoniker.Net70, baseline: true)] +[SimpleJob(RuntimeMoniker.Net80)] +[SimpleJob(RuntimeMoniker.Net90)] [Orderer(SummaryOrderPolicy.Default)] public class EncodeBenchmark { public static IEnumerable PolylineAlgorithm_Coordinates { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index ea8f13cf..6a9d9660 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -9,8 +9,9 @@ namespace PolylineAlgorithm.Benchmarks; internal class Program { static void Main(string[] args) { - BenchmarkSwitcher - .FromAssembly(typeof(Program).Assembly) - .Run(args); + BenchmarkRunner + .Run(); + BenchmarkRunner + .Run(); } } From 30eadac562e886f80c80c0797a0996485119b8fd Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 19:51:46 +0100 Subject: [PATCH 103/352] Revert "refacroteed benchmarks" This reverts commit 3b4b275f9dd998a5f278d0b82ac2c38b927b4cc4. --- .github/workflows/dotnet.yml | 22 +++++++++---------- .../DecodeBenchmark.cs | 5 +---- .../EncodeBenchmark.cs | 4 ---- .../PolylineAlgorithm.Benchmarks/Program.cs | 7 +++--- 4 files changed, 14 insertions(+), 24 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 3af4b90a..a586ad41 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -60,6 +60,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] + netversion: [7, 8, 9] concurrency: group: benchmark @@ -69,18 +70,15 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Setup .NET 7 + - name: Setup .NET ${{ matrix.netversion }} uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.x - - name: Setup .NET 8 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 8.x - - name: Setup .NET 9 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 9.x + dotnet-version: ${{ matrix.netversion }}.x + - name: Fix libssl + if: ${{ matrix.netversion == 5 && matrix.os == 'ubuntu-latest' }} + run: | + wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb + sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb - uses: actions/download-artifact@v4 with: name: build @@ -88,7 +86,7 @@ jobs: merge-multiple: true - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --configuration Release + run: dotnet run --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' - name: Encode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --configuration Release \ No newline at end of file + run: dotnet run --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs index 7c2251db..06bdf75d 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs @@ -7,17 +7,14 @@ namespace PolylineAlgorithm.Benchmarks; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; -using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; using Cloudikka.PolylineAlgorithm.Encoding; using PolylineAlgorithm; using PolylinerNet; +using System.Collections.Generic; [RankColumn] [MemoryDiagnoser] -[SimpleJob(RuntimeMoniker.Net70, baseline: true)] -[SimpleJob(RuntimeMoniker.Net80)] -[SimpleJob(RuntimeMoniker.Net90)] [Orderer(SummaryOrderPolicy.Default)] public class DecodeBenchmark { private readonly Consumer _consumer = new(); diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs index b995e56b..4fc2cf6a 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs @@ -7,7 +7,6 @@ namespace PolylineAlgorithm.Benchmarks; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; -using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; using Cloudikka.PolylineAlgorithm.Encoding; using PolylineAlgorithm; @@ -16,9 +15,6 @@ namespace PolylineAlgorithm.Benchmarks; [RankColumn] [MemoryDiagnoser] -[SimpleJob(RuntimeMoniker.Net70, baseline: true)] -[SimpleJob(RuntimeMoniker.Net80)] -[SimpleJob(RuntimeMoniker.Net90)] [Orderer(SummaryOrderPolicy.Default)] public class EncodeBenchmark { public static IEnumerable PolylineAlgorithm_Coordinates { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index 6a9d9660..ea8f13cf 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -9,9 +9,8 @@ namespace PolylineAlgorithm.Benchmarks; internal class Program { static void Main(string[] args) { - BenchmarkRunner - .Run(); - BenchmarkRunner - .Run(); + BenchmarkSwitcher + .FromAssembly(typeof(Program).Assembly) + .Run(args); } } From 29c7a75bcb89a2b3dff5c4a56f14c64848d495a3 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 19:52:40 +0100 Subject: [PATCH 104/352] what --- .github/workflows/dotnet.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index a586ad41..22fe2ccb 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -60,7 +60,6 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - netversion: [7, 8, 9] concurrency: group: benchmark From 0e224cb2920db7534b2821fc44a3b4607f84a057 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 19:56:11 +0100 Subject: [PATCH 105/352] fixc --- .github/workflows/dotnet.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 22fe2ccb..227ef0ab 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -69,10 +69,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Setup .NET ${{ matrix.netversion }} + - name: Setup .NET 9 uses: actions/setup-dotnet@v3 with: - dotnet-version: ${{ matrix.netversion }}.x + dotnet-version: 9.x - name: Fix libssl if: ${{ matrix.netversion == 5 && matrix.os == 'ubuntu-latest' }} run: | @@ -85,7 +85,7 @@ jobs: merge-multiple: true - name: Decode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*DecodeBenchmark*' + run: dotnet run --configuration Release - name: Encode Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --configuration Release --framework net${{ matrix.netversion }}.0 --filter '*EncodeBenchmark*' \ No newline at end of file + run: dotnet run --configuration Release \ No newline at end of file From 0b72efb86097640b0a5fa509d0efb195bede7c8f Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 20:01:14 +0100 Subject: [PATCH 106/352] fix --- .github/workflows/dotnet.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 227ef0ab..d39f6efe 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -60,6 +60,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] + netversion: [7, 8, 9] concurrency: group: benchmark @@ -69,10 +70,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Setup .NET 9 + - name: Setup .NET ${{ matrix.netversion }} uses: actions/setup-dotnet@v3 with: - dotnet-version: 9.x + dotnet-version: ${{ matrix.netversion }}.x - name: Fix libssl if: ${{ matrix.netversion == 5 && matrix.os == 'ubuntu-latest' }} run: | @@ -83,9 +84,6 @@ jobs: name: build path: . merge-multiple: true - - name: Decode Benchmark - working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --configuration Release - - name: Encode Benchmark + - name: Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --configuration Release \ No newline at end of file + run: dotnet run --configuration Release --framework net${{ matrix.netversion }}.0 \ No newline at end of file From e2ac4d67d221c57940d8173a0730c6fd8fd2c5a3 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 20:03:48 +0100 Subject: [PATCH 107/352] what happening --- .github/workflows/dotnet.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d39f6efe..82fdc96d 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -62,10 +62,6 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] netversion: [7, 8, 9] - concurrency: - group: benchmark - cancel-in-progress: false - runs-on: ${{ matrix.os }} steps: From 1d260fd526a2ba2fcafecf33593d46664d84eef7 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 20:13:05 +0100 Subject: [PATCH 108/352] uugghh --- .github/workflows/dotnet.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 82fdc96d..c8f8a188 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -66,10 +66,18 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Setup .NET ${{ matrix.netversion }} + - name: Setup .NET 7 uses: actions/setup-dotnet@v3 with: - dotnet-version: ${{ matrix.netversion }}.x + dotnet-version: 7.x + - name: Setup .NET 8 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 8.x + - name: Setup .NET 9 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 9.x - name: Fix libssl if: ${{ matrix.netversion == 5 && matrix.os == 'ubuntu-latest' }} run: | From 2bcfdd67d4e0baa8ece8b4d5ab8a6b8aa7963ca6 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 20:17:53 +0100 Subject: [PATCH 109/352] fix fix fix --- .github/workflows/dotnet.yml | 2 +- benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs | 5 ++++- benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs | 5 ++++- benchmarks/PolylineAlgorithm.Benchmarks/Program.cs | 7 ++++--- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c8f8a188..84418156 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -90,4 +90,4 @@ jobs: merge-multiple: true - name: Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --configuration Release --framework net${{ matrix.netversion }}.0 \ No newline at end of file + run: dotnet run --configuration Release \ No newline at end of file diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs index 06bdf75d..c0492d9b 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs @@ -7,14 +7,17 @@ namespace PolylineAlgorithm.Benchmarks; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; using Cloudikka.PolylineAlgorithm.Encoding; using PolylineAlgorithm; using PolylinerNet; -using System.Collections.Generic; [RankColumn] [MemoryDiagnoser] +[SimpleJob(RuntimeMoniker.Net70)] +[SimpleJob(RuntimeMoniker.Net80)] +[SimpleJob(RuntimeMoniker.Net90)] [Orderer(SummaryOrderPolicy.Default)] public class DecodeBenchmark { private readonly Consumer _consumer = new(); diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs index 4fc2cf6a..f4e722ce 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs @@ -6,7 +6,7 @@ namespace PolylineAlgorithm.Benchmarks; using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; using Cloudikka.PolylineAlgorithm.Encoding; using PolylineAlgorithm; @@ -15,6 +15,9 @@ namespace PolylineAlgorithm.Benchmarks; [RankColumn] [MemoryDiagnoser] +[SimpleJob(RuntimeMoniker.Net70)] +[SimpleJob(RuntimeMoniker.Net80)] +[SimpleJob(RuntimeMoniker.Net90)] [Orderer(SummaryOrderPolicy.Default)] public class EncodeBenchmark { public static IEnumerable PolylineAlgorithm_Coordinates { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index ea8f13cf..6a9d9660 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -9,8 +9,9 @@ namespace PolylineAlgorithm.Benchmarks; internal class Program { static void Main(string[] args) { - BenchmarkSwitcher - .FromAssembly(typeof(Program).Assembly) - .Run(args); + BenchmarkRunner + .Run(); + BenchmarkRunner + .Run(); } } From 17c7ee40f7a9849d53565ca45b968761218f0266 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 20:20:26 +0100 Subject: [PATCH 110/352] sdger --- .github/workflows/dotnet.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 84418156..ce603b7d 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -60,7 +60,6 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - netversion: [7, 8, 9] runs-on: ${{ matrix.os }} From ea454946cf9e4d761fea7f34a7ca3437484cf35e Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 20:21:55 +0100 Subject: [PATCH 111/352] title update --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index ce603b7d..b15e7b98 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -54,7 +54,7 @@ jobs: run: dotnet test --no-restore --no-build --configuration Release --verbosity normal benchmark: - name: Benchmark with .NET ${{ matrix.netversion }}.0 on ${{ matrix.os }} + name: Benchmarks on ${{ matrix.os }} needs: [build] strategy: From 1bfcdff8592e9fc7cbb33fb62839758c22405bcc Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 20:24:42 +0100 Subject: [PATCH 112/352] okay try it --- benchmarks/PolylineAlgorithm.Benchmarks/Program.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index 6a9d9660..ea8f13cf 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -9,9 +9,8 @@ namespace PolylineAlgorithm.Benchmarks; internal class Program { static void Main(string[] args) { - BenchmarkRunner - .Run(); - BenchmarkRunner - .Run(); + BenchmarkSwitcher + .FromAssembly(typeof(Program).Assembly) + .Run(args); } } From 5e56159288cde61e9be8ab21bed9e3a228173f70 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 20:32:04 +0100 Subject: [PATCH 113/352] fix --- benchmarks/PolylineAlgorithm.Benchmarks/Program.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index ea8f13cf..fb23641b 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -5,12 +5,20 @@ namespace PolylineAlgorithm.Benchmarks; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Environments; +using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Running; internal class Program { static void Main(string[] args) { + var config = DefaultConfig.Instance + .AddJob(Job.Default.WithRuntime(CoreRuntime.Core70)) + .AddJob(Job.Default.WithRuntime(CoreRuntime.Core80)) + .AddJob(Job.Default.WithRuntime(CoreRuntime.Core90)); + BenchmarkSwitcher .FromAssembly(typeof(Program).Assembly) - .Run(args); + .Run(args, config); } } From 93d0d651cd87434af9cdb521addac191071cba93 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Wed, 29 Jan 2025 20:34:56 +0100 Subject: [PATCH 114/352] added runtimes --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b15e7b98..761577d2 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -89,4 +89,4 @@ jobs: merge-multiple: true - name: Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --configuration Release \ No newline at end of file + run: dotnet run --configuration Release --runtimes net7.0 net8.0 net9.0 \ No newline at end of file From 7f250b9b45566f46f6ebd1568b604e947abd58fe Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 30 Jan 2025 16:28:10 +0100 Subject: [PATCH 115/352] updated benchmark dotnet command --- .github/workflows/dotnet.yml | 2 +- .../PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 761577d2..33588a37 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -89,4 +89,4 @@ jobs: merge-multiple: true - name: Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run --configuration Release --runtimes net7.0 net8.0 net9.0 \ No newline at end of file + run: dotnet run -c Release -f net9.0 --runtimes net7.0 net8.0 net9.0 \ No newline at end of file diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs index f4e722ce..7f037177 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs @@ -20,26 +20,26 @@ namespace PolylineAlgorithm.Benchmarks; [SimpleJob(RuntimeMoniker.Net90)] [Orderer(SummaryOrderPolicy.Default)] public class EncodeBenchmark { - public static IEnumerable PolylineAlgorithm_Coordinates { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; - public static List PolylinerNet_PolylinePoint { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; - public static IEnumerable<(double, double)> Cloudikka_PolylineEncoding_Tuple { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; + public static IEnumerable Coordinates_Enumerable { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; + public static List PolylinePoint_List { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; + public static IEnumerable<(double, double)> Tuple_Enumerable { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; [Benchmark(Baseline = true)] public ReadOnlySpan PolylineEncoder_Encode() { var encoder = new PolylineEncoder(); - return encoder.Encode(PolylineAlgorithm_Coordinates); + return encoder.Encode(Coordinates_Enumerable); } [Benchmark] public string Polyliner_Encode() { var polyliner = new Polyliner(); - return polyliner.Encode(PolylinerNet_PolylinePoint); + return polyliner.Encode(PolylinePoint_List); } [Benchmark] public string Cloudikka_PolylineEncoding_Encode() { var polyliner = new PolylineEncoding(); - return polyliner.Encode(Cloudikka_PolylineEncoding_Tuple); + return polyliner.Encode(Tuple_Enumerable); } } From 82549391fa5190375c3ad3009b9e3083ff8166fb Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 30 Jan 2025 16:30:41 +0100 Subject: [PATCH 116/352] added filter to becnhmark cmd --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 33588a37..5399602e 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -89,4 +89,4 @@ jobs: merge-multiple: true - name: Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release -f net9.0 --runtimes net7.0 net8.0 net9.0 \ No newline at end of file + run: dotnet run -c Release -f net9.0 --runtimes net7.0 net8.0 net9.0 --filter '*Benchmark*' \ No newline at end of file From 3ee9696d8d77d35628b93ce5e536d1b1ac7e52e6 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 30 Jan 2025 17:02:12 +0100 Subject: [PATCH 117/352] added more .NET framewroks to becnhmarks --- .github/workflows/dotnet.yml | 32 +++++++++++++++++-- .../DecodeBenchmark.cs | 7 ++++ .../EncodeBenchmark.cs | 7 ++++ .../PolylineAlgorithm.Benchmarks/Program.cs | 7 ++++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 5399602e..1339eedf 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -54,7 +54,7 @@ jobs: run: dotnet test --no-restore --no-build --configuration Release --verbosity normal benchmark: - name: Benchmarks on ${{ matrix.os }} + name: Benchmark on ${{ matrix.os }} needs: [build] strategy: @@ -65,6 +65,34 @@ jobs: steps: - uses: actions/checkout@v3 + - name: Setup .NET Core 2.0 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 2.0.x + - name: Setup .NET Core 2.1 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 2.1.x + - name: Setup .NET Core 2.2 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 2.2.x + - name: Setup .NET Core 3.0 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 3.0.x + - name: Setup .NET Core 3.1 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 3.1.x + - name: Setup .NET 5 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 5.x + - name: Setup .NET 6 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 6.x - name: Setup .NET 7 uses: actions/setup-dotnet@v3 with: @@ -89,4 +117,4 @@ jobs: merge-multiple: true - name: Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release -f net9.0 --runtimes net7.0 net8.0 net9.0 --filter '*Benchmark*' \ No newline at end of file + run: dotnet run -c Release -f net9.0 --runtimes netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1 net5.0 net6.0 net7.0 net8.0 net9.0 --filter '*Benchmark*' \ No newline at end of file diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs index c0492d9b..1b9e79b6 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs @@ -15,6 +15,13 @@ namespace PolylineAlgorithm.Benchmarks; [RankColumn] [MemoryDiagnoser] +[SimpleJob(RuntimeMoniker.NetCoreApp20)] +[SimpleJob(RuntimeMoniker.NetCoreApp21)] +[SimpleJob(RuntimeMoniker.NetCoreApp22)] +[SimpleJob(RuntimeMoniker.NetCoreApp30)] +[SimpleJob(RuntimeMoniker.NetCoreApp31)] +[SimpleJob(RuntimeMoniker.Net50)] +[SimpleJob(RuntimeMoniker.Net60)] [SimpleJob(RuntimeMoniker.Net70)] [SimpleJob(RuntimeMoniker.Net80)] [SimpleJob(RuntimeMoniker.Net90)] diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs index 7f037177..166603bc 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs @@ -15,6 +15,13 @@ namespace PolylineAlgorithm.Benchmarks; [RankColumn] [MemoryDiagnoser] +[SimpleJob(RuntimeMoniker.NetCoreApp20)] +[SimpleJob(RuntimeMoniker.NetCoreApp21)] +[SimpleJob(RuntimeMoniker.NetCoreApp22)] +[SimpleJob(RuntimeMoniker.NetCoreApp30)] +[SimpleJob(RuntimeMoniker.NetCoreApp31)] +[SimpleJob(RuntimeMoniker.Net50)] +[SimpleJob(RuntimeMoniker.Net60)] [SimpleJob(RuntimeMoniker.Net70)] [SimpleJob(RuntimeMoniker.Net80)] [SimpleJob(RuntimeMoniker.Net90)] diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index fb23641b..fb20a278 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -13,6 +13,13 @@ namespace PolylineAlgorithm.Benchmarks; internal class Program { static void Main(string[] args) { var config = DefaultConfig.Instance + .AddJob(Job.Default.WithRuntime(CoreRuntime.Core20)) + .AddJob(Job.Default.WithRuntime(CoreRuntime.Core21)) + .AddJob(Job.Default.WithRuntime(CoreRuntime.Core22)) + .AddJob(Job.Default.WithRuntime(CoreRuntime.Core30)) + .AddJob(Job.Default.WithRuntime(CoreRuntime.Core31)) + .AddJob(Job.Default.WithRuntime(CoreRuntime.Core50)) + .AddJob(Job.Default.WithRuntime(CoreRuntime.Core60)) .AddJob(Job.Default.WithRuntime(CoreRuntime.Core70)) .AddJob(Job.Default.WithRuntime(CoreRuntime.Core80)) .AddJob(Job.Default.WithRuntime(CoreRuntime.Core90)); From ad804b2b6f3a893f5e89bdcfd0b703394d813ccf Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 30 Jan 2025 17:12:56 +0100 Subject: [PATCH 118/352] merged install .net sdk version to one --- .github/workflows/dotnet.yml | 56 ++++++++++-------------------------- 1 file changed, 15 insertions(+), 41 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 1339eedf..7c1f6b14 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -18,7 +18,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install .NET 9 - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: 9.x - name: Restore @@ -42,7 +42,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Setup .NET 9 - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: 9.x - uses: actions/download-artifact@v4 @@ -65,46 +65,20 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Setup .NET Core 2.0 - uses: actions/setup-dotnet@v3 + - name: Install .NET SDK + uses: actions/setup-dotnet@v4 with: - dotnet-version: 2.0.x - - name: Setup .NET Core 2.1 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 2.1.x - - name: Setup .NET Core 2.2 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 2.2.x - - name: Setup .NET Core 3.0 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 3.0.x - - name: Setup .NET Core 3.1 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 3.1.x - - name: Setup .NET 5 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 5.x - - name: Setup .NET 6 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 6.x - - name: Setup .NET 7 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 7.x - - name: Setup .NET 8 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 8.x - - name: Setup .NET 9 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 9.x + dotnet-version: | + 2.0.x + 2.1.x + 2.2.x + 3.0.x + 3.1.x + 5.x + 6.x + 7.x + 8.x + 9.x - name: Fix libssl if: ${{ matrix.netversion == 5 && matrix.os == 'ubuntu-latest' }} run: | From c5cbfb608872042eb4d979150fe3200511c03789 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 30 Jan 2025 17:18:56 +0100 Subject: [PATCH 119/352] added nema to download artifact step --- .github/workflows/dotnet.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 7c1f6b14..bdd695ab 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -84,7 +84,8 @@ jobs: run: | wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb - - uses: actions/download-artifact@v4 + - name: Download Build Artifact + uses: actions/download-artifact@v4 with: name: build path: . From 8c105cb33bd6188890b902411c9da7730a50ee7f Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 30 Jan 2025 17:27:45 +0100 Subject: [PATCH 120/352] downgraded setup-dotnet step to v3 --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index bdd695ab..ee199edf 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -66,7 +66,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install .NET SDK - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v3 with: dotnet-version: | 2.0.x From 5e5d3ce86b684042317ad56566efa1edb55e5dca Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 30 Jan 2025 17:42:07 +0100 Subject: [PATCH 121/352] v2 --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index ee199edf..bde7157b 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -66,7 +66,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install .NET SDK - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v2 with: dotnet-version: | 2.0.x From d0edbafb60fb17ff5c128100be6b4735f115fbf4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 30 Jan 2025 17:55:00 +0100 Subject: [PATCH 122/352] removed unused step --- .github/workflows/dotnet.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index bde7157b..42dfcaea 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -79,11 +79,6 @@ jobs: 7.x 8.x 9.x - - name: Fix libssl - if: ${{ matrix.netversion == 5 && matrix.os == 'ubuntu-latest' }} - run: | - wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb - sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.23_amd64.deb - name: Download Build Artifact uses: actions/download-artifact@v4 with: From e2afacc7b5a014a9bfcacc10f1fe586cedbc33e3 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 30 Jan 2025 18:01:11 +0100 Subject: [PATCH 123/352] extracted benchmark job to separate file --- .github/workflows/benchmark.yml | 65 +++++++++++++++++++++++++++++++++ .github/workflows/dotnet.yml | 41 +-------------------- 2 files changed, 66 insertions(+), 40 deletions(-) create mode 100644 .github/workflows/benchmark.yml diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml new file mode 100644 index 00000000..1b607dba --- /dev/null +++ b/.github/workflows/benchmark.yml @@ -0,0 +1,65 @@ +name: .NET + +on: + push: + branches: [ "main" ] + +jobs: + build: + name: Build with .NET 9 + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Install .NET 9 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.x + - name: Restore + run: dotnet restore + - name: Build + run: dotnet build --no-restore --configuration Release + - name: Upload + uses: actions/upload-artifact@v4 + with: + name: build + path: | + **/bin/* + **/obj/* + + benchmark: + name: Benchmark on ${{ matrix.os }} + needs: [build] + + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + - name: Install .NET SDK + uses: actions/setup-dotnet@v2 + with: + dotnet-version: | + 2.0.x + 2.1.x + 2.2.x + 3.0.x + 3.1.x + 5.x + 6.x + 7.x + 8.x + 9.x + - name: Download + uses: actions/download-artifact@v4 + with: + name: build + path: . + merge-multiple: true + - name: Benchmark + working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks + run: dotnet run -c Release -f net9.0 --runtimes netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1 net5.0 net6.0 net7.0 net8.0 net9.0 --filter '*Benchmark*' \ No newline at end of file diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 42dfcaea..945108fe 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -1,6 +1,3 @@ -# This workflow will build a .NET project -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net - name: .NET on: @@ -51,40 +48,4 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal - - benchmark: - name: Benchmark on ${{ matrix.os }} - needs: [build] - - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - - runs-on: ${{ matrix.os }} - - steps: - - uses: actions/checkout@v3 - - name: Install .NET SDK - uses: actions/setup-dotnet@v2 - with: - dotnet-version: | - 2.0.x - 2.1.x - 2.2.x - 3.0.x - 3.1.x - 5.x - 6.x - 7.x - 8.x - 9.x - - name: Download Build Artifact - uses: actions/download-artifact@v4 - with: - name: build - path: . - merge-multiple: true - - name: Benchmark - working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release -f net9.0 --runtimes netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1 net5.0 net6.0 net7.0 net8.0 net9.0 --filter '*Benchmark*' \ No newline at end of file + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal \ No newline at end of file From bc4b183844342e528496b3d76f868f4252bb57ea Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 30 Jan 2025 18:12:13 +0100 Subject: [PATCH 124/352] reanmed workflow title --- .github/workflows/benchmark.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 1b607dba..8220d343 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -1,4 +1,4 @@ -name: .NET +name: Benchmark on: push: From df0ac672aac4533c5fbb18a1266a370826451002 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 30 Jan 2025 18:19:23 +0100 Subject: [PATCH 125/352] added [MarkdownExporter] --- benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs | 1 + benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs index 1b9e79b6..2df719b1 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs @@ -15,6 +15,7 @@ namespace PolylineAlgorithm.Benchmarks; [RankColumn] [MemoryDiagnoser] +[MarkdownExporter] [SimpleJob(RuntimeMoniker.NetCoreApp20)] [SimpleJob(RuntimeMoniker.NetCoreApp21)] [SimpleJob(RuntimeMoniker.NetCoreApp22)] diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs index 166603bc..351e432d 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs @@ -15,6 +15,7 @@ namespace PolylineAlgorithm.Benchmarks; [RankColumn] [MemoryDiagnoser] +[MarkdownExporter] [SimpleJob(RuntimeMoniker.NetCoreApp20)] [SimpleJob(RuntimeMoniker.NetCoreApp21)] [SimpleJob(RuntimeMoniker.NetCoreApp22)] From f776ed3ec53b9810dd6475c12eadc86ffc65cc17 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 30 Jan 2025 18:19:40 +0100 Subject: [PATCH 126/352] updated README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index afbc48ce..ecd8117d 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@ -# .NET Polyline Algorithm (.NET Standard 2.0) +# .NET Polyline Algorithm (.NET Standard 2.1) -Lightweight .NET Standard 2.0 library implementing Google Polyline Algorithm. Designed with respect to flexibility, but still with easy to use. +Lightweight high=performance .NET Standard 2.1 library implementing Google Polyline Algorithm. ## Prerequisites -.NET Polyline Algorithm is avalable as nuget package Cloudikka.PolylineAlgorithm targeting .NET Standard 2.0. +.NET Polyline Algorithm is avalable as a NuGet package PolylineAlgorithm targeting .NET Standard 2.1. Command line: -`Install-Package Cloudikka.PolylineAlgorithm` +`Install-Package PolylineAlgorithm` NuGet Package Manager: -`Cloudikka.PolylineAlgorithm` +`PolylineAlgorithm` ## Hot to use it From b8344f4906dcd2eade8ab9e50506daff043d786b Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 30 Jan 2025 18:35:28 +0100 Subject: [PATCH 127/352] filter takes all benchmarks --- .github/workflows/benchmark.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 8220d343..d410f655 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -62,4 +62,4 @@ jobs: merge-multiple: true - name: Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release -f net9.0 --runtimes netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1 net5.0 net6.0 net7.0 net8.0 net9.0 --filter '*Benchmark*' \ No newline at end of file + run: dotnet run -c Release -f net9.0 --runtimes netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1 net5.0 net6.0 net7.0 net8.0 net9.0 --filter * \ No newline at end of file From 35869c2a86ec78cc0598808d5296425318815eca Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Thu, 30 Jan 2025 23:03:52 +0100 Subject: [PATCH 128/352] updated benchmark runs settings --- .github/workflows/benchmark.yml | 2 +- .../PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs | 13 +------------ .../PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs | 13 +------------ 3 files changed, 3 insertions(+), 25 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index d410f655..e9f01f59 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -62,4 +62,4 @@ jobs: merge-multiple: true - name: Benchmark working-directory: ./benchmarks/PolylineAlgorithm.Benchmarks - run: dotnet run -c Release -f net9.0 --runtimes netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1 net5.0 net6.0 net7.0 net8.0 net9.0 --filter * \ No newline at end of file + run: dotnet run -c Release -f net9.0 --filter * \ No newline at end of file diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs index 2df719b1..3dfa5497 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs @@ -7,7 +7,6 @@ namespace PolylineAlgorithm.Benchmarks; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; -using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; using Cloudikka.PolylineAlgorithm.Encoding; using PolylineAlgorithm; @@ -16,17 +15,7 @@ namespace PolylineAlgorithm.Benchmarks; [RankColumn] [MemoryDiagnoser] [MarkdownExporter] -[SimpleJob(RuntimeMoniker.NetCoreApp20)] -[SimpleJob(RuntimeMoniker.NetCoreApp21)] -[SimpleJob(RuntimeMoniker.NetCoreApp22)] -[SimpleJob(RuntimeMoniker.NetCoreApp30)] -[SimpleJob(RuntimeMoniker.NetCoreApp31)] -[SimpleJob(RuntimeMoniker.Net50)] -[SimpleJob(RuntimeMoniker.Net60)] -[SimpleJob(RuntimeMoniker.Net70)] -[SimpleJob(RuntimeMoniker.Net80)] -[SimpleJob(RuntimeMoniker.Net90)] -[Orderer(SummaryOrderPolicy.Default)] +[Orderer(SummaryOrderPolicy.Method)] public class DecodeBenchmark { private readonly Consumer _consumer = new(); public static string String_Polyline { get; } = "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"; diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs index 351e432d..2843d98c 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs @@ -6,7 +6,6 @@ namespace PolylineAlgorithm.Benchmarks; using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; using Cloudikka.PolylineAlgorithm.Encoding; using PolylineAlgorithm; @@ -16,17 +15,7 @@ namespace PolylineAlgorithm.Benchmarks; [RankColumn] [MemoryDiagnoser] [MarkdownExporter] -[SimpleJob(RuntimeMoniker.NetCoreApp20)] -[SimpleJob(RuntimeMoniker.NetCoreApp21)] -[SimpleJob(RuntimeMoniker.NetCoreApp22)] -[SimpleJob(RuntimeMoniker.NetCoreApp30)] -[SimpleJob(RuntimeMoniker.NetCoreApp31)] -[SimpleJob(RuntimeMoniker.Net50)] -[SimpleJob(RuntimeMoniker.Net60)] -[SimpleJob(RuntimeMoniker.Net70)] -[SimpleJob(RuntimeMoniker.Net80)] -[SimpleJob(RuntimeMoniker.Net90)] -[Orderer(SummaryOrderPolicy.Default)] +[Orderer(SummaryOrderPolicy.Method)] public class EncodeBenchmark { public static IEnumerable Coordinates_Enumerable { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; public static List PolylinePoint_List { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; From bacad8abaf23b083a3cf8221d080abe74e39a6dc Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Fri, 31 Jan 2025 01:26:29 +0100 Subject: [PATCH 129/352] added benchmark comparison --- README.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/README.md b/README.md index ecd8117d..42d218c2 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,87 @@ There may be a scenario you need to pass and return different types to and from string polyline = encoding.Encode(coordinates); ``` +### Performance + +#### Decode + +``` + +BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.2894) +Apple Silicon, 4 CPU, 4 logical and 4 physical cores +.NET SDK 9.0.102 + [Host] : .NET 9.0.1 (9.0.124.61010), Arm64 RyuJIT AdvSIMD + Job-CJKHIS : .NET 5.0.17 (5.0.1722.21314), Arm64 RyuJIT AdvSIMD + Job-GAHPKM : .NET 6.0.36 (6.0.3624.51421), Arm64 RyuJIT AdvSIMD + Job-KWIIGA : .NET 7.0.20 (7.0.2024.26716), Arm64 RyuJIT AdvSIMD + Job-ZMWUEM : .NET 8.0.12 (8.0.1224.60305), Arm64 RyuJIT AdvSIMD + Job-EQIHVN : .NET 9.0.1 (9.0.124.61010), Arm64 RyuJIT AdvSIMD + + +``` +| Method | Runtime | Mean | Error | StdDev | Ratio | RatioSD | Rank | Gen0 | Gen1 | Allocated | Alloc Ratio | +|---------------------------------- |--------- |-----------:|---------:|---------:|------:|--------:|-----:|-------:|-------:|----------:|------------:| +| **Cloudikka_PolylineEncoding_Decode** | **.NET 5.0** | **1,768.2 ns** | **7.36 ns** | **6.88 ns** | **1.29** | **0.01** | **3** | **0.4959** | **0.0019** | **3120 B** | **3.82** | +| **PolylineDecoder_Decode** | **.NET 5.0** | **1,367.1 ns** | **7.91 ns** | **6.61 ns** | **1.00** | **0.01** | **2** | **0.1297** | **-** | **816 B** | **1.00** | +| **Polyliner_Decode** | **.NET 5.0** | **1,218.0 ns** | **3.79 ns** | **3.17 ns** | **0.89** | **0.00** | **1** | **0.5169** | **0.0057** | **3248 B** | **3.98** | +| | | | | | | | | | | | | +| **Cloudikka_PolylineEncoding_Decode** | **.NET 6.0** | **1,763.8 ns** | **4.51 ns** | **4.00 ns** | **1.38** | **0.01** | **3** | **0.4959** | **0.0019** | **3120 B** | **3.82** | +| **PolylineDecoder_Decode** | **.NET 6.0** | **1,277.5 ns** | **4.43 ns** | **4.14 ns** | **1.00** | **0.00** | **2** | **0.1297** | **-** | **816 B** | **1.00** | +| **Polyliner_Decode** | **.NET 6.0** | **837.2 ns** | **2.49 ns** | **2.21 ns** | **0.66** | **0.00** | **1** | **0.5169** | **0.0057** | **3248 B** | **3.98** | +| | | | | | | | | | | | | +| **Cloudikka_PolylineEncoding_Decode** | **.NET 7.0** | **1,387.6 ns** | **24.18 ns** | **22.62 ns** | **1.12** | **0.02** | **2** | **1.4915** | **-** | **3120 B** | **3.82** | +| **PolylineDecoder_Decode** | **.NET 7.0** | **1,237.5 ns** | **3.05 ns** | **2.86 ns** | **1.00** | **0.00** | **1** | **0.3891** | **-** | **816 B** | **1.00** | +| **Polyliner_Decode** | **.NET 7.0** | **1,230.6 ns** | **2.08 ns** | **1.84 ns** | **0.99** | **0.00** | **1** | **1.5526** | **-** | **3248 B** | **3.98** | +| | | | | | | | | | | | | +| **Cloudikka_PolylineEncoding_Decode** | **.NET 8.0** | **766.0 ns** | **3.39 ns** | **3.17 ns** | **1.49** | **0.01** | **3** | **1.4915** | **-** | **3120 B** | **3.82** | +| **PolylineDecoder_Decode** | **.NET 8.0** | **513.9 ns** | **1.21 ns** | **1.14 ns** | **1.00** | **0.00** | **1** | **0.3901** | **-** | **816 B** | **1.00** | +| **Polyliner_Decode** | **.NET 8.0** | **704.4 ns** | **1.38 ns** | **1.29 ns** | **1.37** | **0.00** | **2** | **1.5526** | **-** | **3248 B** | **3.98** | +| | | | | | | | | | | | | +| **Cloudikka_PolylineEncoding_Decode** | **.NET 9.0** | **782.5 ns** | **1.50 ns** | **1.33 ns** | **1.57** | **0.00** | **3** | **1.4915** | **-** | **3120 B** | **3.82** | +| **PolylineDecoder_Decode** | **.NET 9.0** | **498.7 ns** | **1.27 ns** | **1.19 ns** | **1.00** | **0.00** | **1** | **0.3901** | **-** | **816 B** | **1.00** | +| **Polyliner_Decode** | **.NET 9.0** | **705.2 ns** | **1.30 ns** | **1.15 ns** | **1.41** | **0.00** | **2** | **1.5526** | **-** | **3248 B** | **3.98** | + + +#### Encode + +``` + +BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.2894) +Apple Silicon, 4 CPU, 4 logical and 4 physical cores +.NET SDK 9.0.102 + [Host] : .NET 9.0.1 (9.0.124.61010), Arm64 RyuJIT AdvSIMD + Job-CJKHIS : .NET 5.0.17 (5.0.1722.21314), Arm64 RyuJIT AdvSIMD + Job-GAHPKM : .NET 6.0.36 (6.0.3624.51421), Arm64 RyuJIT AdvSIMD + Job-KWIIGA : .NET 7.0.20 (7.0.2024.26716), Arm64 RyuJIT AdvSIMD + Job-ZMWUEM : .NET 8.0.12 (8.0.1224.60305), Arm64 RyuJIT AdvSIMD + Job-EQIHVN : .NET 9.0.1 (9.0.124.61010), Arm64 RyuJIT AdvSIMD + + +``` +| Method | Runtime | Mean | Error | StdDev | Ratio | RatioSD | Rank | Gen0 | Gen1 | Allocated | Alloc Ratio | +|---------------------------------- |--------- |-----------:|---------:|---------:|------:|--------:|-----:|-------:|-------:|----------:|------------:| +| **Cloudikka_PolylineEncoding_Encode** | **.NET 5.0** | **8,936.5 ns** | **26.81 ns** | **25.07 ns** | **8.18** | **0.04** | **3** | **2.2583** | **-** | **13.91 KB** | **7.95** | +| **PolylineEncoder_Encode** | **.NET 5.0** | **1,092.4 ns** | **4.73 ns** | **4.42 ns** | **1.00** | **0.01** | **1** | **0.2842** | **-** | **1.75 KB** | **1.00** | +| **Polyliner_Encode** | **.NET 5.0** | **1,291.0 ns** | **4.05 ns** | **3.16 ns** | **1.18** | **0.01** | **2** | **0.3643** | **0.0019** | **2.23 KB** | **1.28** | +| | | | | | | | | | | | | +| **Cloudikka_PolylineEncoding_Encode** | **.NET 6.0** | **7,640.7 ns** | **21.80 ns** | **20.39 ns** | **7.56** | **0.04** | **3** | **2.2583** | **-** | **13.91 KB** | **7.95** | +| **PolylineEncoder_Encode** | **.NET 6.0** | **1,011.3 ns** | **4.33 ns** | **4.05 ns** | **1.00** | **0.01** | **1** | **0.2842** | **-** | **1.75 KB** | **1.00** | +| **Polyliner_Encode** | **.NET 6.0** | **1,080.0 ns** | **3.35 ns** | **3.13 ns** | **1.07** | **0.01** | **2** | **0.3643** | **0.0019** | **2.23 KB** | **1.28** | +| | | | | | | | | | | | | +| **Cloudikka_PolylineEncoding_Encode** | **.NET 7.0** | **6,718.0 ns** | **13.77 ns** | **12.88 ns** | **6.65** | **0.02** | **3** | **6.8054** | **-** | **13.91 KB** | **7.95** | +| **PolylineEncoder_Encode** | **.NET 7.0** | **1,010.1 ns** | **3.32 ns** | **3.11 ns** | **1.00** | **0.00** | **1** | **0.8564** | **-** | **1.75 KB** | **1.00** | +| **Polyliner_Encode** | **.NET 7.0** | **1,075.9 ns** | **3.27 ns** | **2.73 ns** | **1.07** | **0.00** | **2** | **1.0929** | **-** | **2.23 KB** | **1.28** | +| | | | | | | | | | | | | +| **Cloudikka_PolylineEncoding_Encode** | **.NET 8.0** | **4,969.5 ns** | **9.29 ns** | **8.24 ns** | **9.53** | **0.03** | **3** | **6.8054** | **-** | **13.91 KB** | **7.95** | +| **PolylineEncoder_Encode** | **.NET 8.0** | **521.4 ns** | **1.37 ns** | **1.28 ns** | **1.00** | **0.00** | **1** | **0.8564** | **-** | **1.75 KB** | **1.00** | +| **Polyliner_Encode** | **.NET 8.0** | **1,020.7 ns** | **2.90 ns** | **2.57 ns** | **1.96** | **0.01** | **2** | **1.0929** | **-** | **2.23 KB** | **1.28** | +| | | | | | | | | | | | | +| **Cloudikka_PolylineEncoding_Encode** | **.NET 9.0** | **3,809.8 ns** | **27.85 ns** | **26.06 ns** | **7.21** | **0.05** | **3** | **4.3335** | **-** | **8.86 KB** | **5.06** | +| **PolylineEncoder_Encode** | **.NET 9.0** | **528.2 ns** | **1.85 ns** | **1.73 ns** | **1.00** | **0.00** | **1** | **0.8564** | **-** | **1.75 KB** | **1.00** | +| **Polyliner_Encode** | **.NET 9.0** | **1,033.9 ns** | **6.30 ns** | **5.89 ns** | **1.96** | **0.01** | **2** | **1.0929** | **-** | **2.23 KB** | **1.28** | + + + ### Documentation Documentation is can be found at https://dropoutcoder.github.io/polyline-algorithm-csharp/api/index.html. From ce4132993bab388e8fb1cec26082737912d6fabb Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Fri, 31 Jan 2025 01:31:12 +0100 Subject: [PATCH 130/352] updated benchmarks --- .../PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs | 11 ++++++----- .../PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs | 13 +++++++------ benchmarks/PolylineAlgorithm.Benchmarks/Program.cs | 10 +++++----- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs index 3dfa5497..735ea409 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/DecodeBenchmark.cs @@ -15,7 +15,7 @@ namespace PolylineAlgorithm.Benchmarks; [RankColumn] [MemoryDiagnoser] [MarkdownExporter] -[Orderer(SummaryOrderPolicy.Method)] +[Orderer(SummaryOrderPolicy.Declared)] public class DecodeBenchmark { private readonly Consumer _consumer = new(); public static string String_Polyline { get; } = "}adrJh}}cVazlw@uykyNhaqeE`vfzG_~kY}~`eTsr{~Cwn~aOty_g@thapJvvoqKxt{sStfahDmtvmIfmiqBhjq|HujpgComs{Z}dhdKcidPymnvBqmquE~qrfI`x{lPf|ftGn~}d_@q}saAurjmu@bwr_DxrfaK~{rO~bidPwfduXwlioFlpum@twvfFpmi~VzxcsOqyejYhh|i@pbnr[twvfF_ueUujvbSa_d~ZkcnjZla~f[pmquEebxo[j}nr@xnn|H{gyiKbh{yH`oenn@y{mpIrbd~EmipgH}fuov@hjqtTp|flAttvkFrym_d@|eyCwn~aOfvdNmeawM??{yxdUcidPca{}D_atqGenzcAlra{@trgWhn{aZ??tluqOgu~sH"; @@ -29,17 +29,18 @@ public void PolylineDecoder_Decode() { decoder.Decode(in polyline).Consume(_consumer); } + [Benchmark] - public void Polyliner_Decode() { + public void Cloudikka_PolylineEncoding_Decode() { string polyline = String_Polyline; - var polyliner = new Polyliner(); + var polyliner = new PolylineEncoding(); polyliner.Decode(polyline).Consume(_consumer); } [Benchmark] - public void Cloudikka_PolylineEncoding_Decode() { + public void Polyliner_Decode() { string polyline = String_Polyline; - var polyliner = new PolylineEncoding(); + var polyliner = new Polyliner(); polyliner.Decode(polyline).Consume(_consumer); } } diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs index 2843d98c..5073750e 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/EncodeBenchmark.cs @@ -15,7 +15,7 @@ namespace PolylineAlgorithm.Benchmarks; [RankColumn] [MemoryDiagnoser] [MarkdownExporter] -[Orderer(SummaryOrderPolicy.Method)] +[Orderer(SummaryOrderPolicy.Declared)] public class EncodeBenchmark { public static IEnumerable Coordinates_Enumerable { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; public static List PolylinePoint_List { get; } = [new(60.81071, -121.40005), new(70.05664, -38.43130), new(37.52379, -84.83755), new(41.85003, 26.25620), new(68.04709, 110.63120), new(61.48922, 50.16245), new(-4.46018, -58.11880), new(-32.16061, -3.27505), new(-50.89185, -55.30630), new(-28.52070, 90.94370), new(35.26009, 93.75620), new(54.83622, 128.91245), new(1.16022, 37.50620), new(-44.26398, -131.24380), new(-33.34325, 154.22495), new(-59.65879, 90.94370), new(-62.38215, 0.94370), new(72.32117, 40.31870), new(64.66910, 2.34995), new(-61.04971, -84.83755), new(77.10238, -91.86880), new(-72.88859, -129.83755), new(-69.24987, -24.36880), new(77.41254, 119.06870), new(-70.69409, 83.91245), new(78.85650, 75.47495), new(26.83989, 140.16245), new(-24.75069, -108.74380), new(30.53968, -145.30630), new(79.12503, 145.78745), new(-34.51006, 133.13120), new(-73.29753, -60.93130), new(-74.08712, 23.44370), new(-76.57404, 100.78745), new(-76.57404, 100.78745), new(39.72082, 103.59995), new(70.99412, 148.59995), new(82.27591, 138.75620), new(78.29964, -3.27505), new(78.29964, -3.27505), new(-8.65039, 47.34995)]; @@ -28,15 +28,16 @@ public ReadOnlySpan PolylineEncoder_Encode() { return encoder.Encode(Coordinates_Enumerable); } - [Benchmark] - public string Polyliner_Encode() { - var polyliner = new Polyliner(); - return polyliner.Encode(PolylinePoint_List); - } [Benchmark] public string Cloudikka_PolylineEncoding_Encode() { var polyliner = new PolylineEncoding(); return polyliner.Encode(Tuple_Enumerable); } + + [Benchmark] + public string Polyliner_Encode() { + var polyliner = new Polyliner(); + return polyliner.Encode(PolylinePoint_List); + } } diff --git a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs index fb20a278..3bfa67bb 100644 --- a/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs +++ b/benchmarks/PolylineAlgorithm.Benchmarks/Program.cs @@ -13,11 +13,11 @@ namespace PolylineAlgorithm.Benchmarks; internal class Program { static void Main(string[] args) { var config = DefaultConfig.Instance - .AddJob(Job.Default.WithRuntime(CoreRuntime.Core20)) - .AddJob(Job.Default.WithRuntime(CoreRuntime.Core21)) - .AddJob(Job.Default.WithRuntime(CoreRuntime.Core22)) - .AddJob(Job.Default.WithRuntime(CoreRuntime.Core30)) - .AddJob(Job.Default.WithRuntime(CoreRuntime.Core31)) + //.AddJob(Job.Default.WithRuntime(CoreRuntime.Core20)) + //.AddJob(Job.Default.WithRuntime(CoreRuntime.Core21)) + //.AddJob(Job.Default.WithRuntime(CoreRuntime.Core22)) + //.AddJob(Job.Default.WithRuntime(CoreRuntime.Core30)) + //.AddJob(Job.Default.WithRuntime(CoreRuntime.Core31)) .AddJob(Job.Default.WithRuntime(CoreRuntime.Core50)) .AddJob(Job.Default.WithRuntime(CoreRuntime.Core60)) .AddJob(Job.Default.WithRuntime(CoreRuntime.Core70)) From 23da85ee6d7622d7c7435a38065263349b917366 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 13:03:31 +0100 Subject: [PATCH 131/352] added code coverage arguments for test cmd --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 945108fe..afbef707 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,4 +48,4 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal \ No newline at end of file + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --logger trx --results-directory code-coverage \ No newline at end of file From 8accc5ff59c950c451a58cd0916c866e4367ce69 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 13:23:48 +0100 Subject: [PATCH 132/352] test code coverage --- .github/workflows/dotnet.yml | 2 +- .../coverlet.runsettings | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/PolylineAlgorithm.Tests/coverlet.runsettings diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index afbef707..786e58c3 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,4 +48,4 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --logger trx --results-directory code-coverage \ No newline at end of file + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --settings coverlet.runsettings \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/coverlet.runsettings b/tests/PolylineAlgorithm.Tests/coverlet.runsettings new file mode 100644 index 00000000..58a2d963 --- /dev/null +++ b/tests/PolylineAlgorithm.Tests/coverlet.runsettings @@ -0,0 +1,22 @@ + + + + + + + json,cobertura,lcov,teamcity,opencover + [coverlet.*.tests?]*,[*]Coverlet.Core* + [coverlet.*]*,[*]Coverlet.Core* + Obsolete,GeneratedCodeAttribute,CompilerGeneratedAttribute + **/dir1/class1.cs,**/dir2/*.cs,**/dir3/**/*.cs, + false + true + true + true + false + MissingAll,MissingAny,None + + + + + \ No newline at end of file From e7e94733e3b28faa64061d9948e4bfe817efb287 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 13:27:54 +0100 Subject: [PATCH 133/352] updated --- .github/workflows/dotnet.yml | 3 ++- tests/{PolylineAlgorithm.Tests => }/coverlet.runsettings | 0 2 files changed, 2 insertions(+), 1 deletion(-) rename tests/{PolylineAlgorithm.Tests => }/coverlet.runsettings (100%) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 786e58c3..c0939642 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,4 +48,5 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --settings coverlet.runsettings \ No newline at end of file + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --settings coverlet.runsettings + working-directory: ./tests/ \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/coverlet.runsettings b/tests/coverlet.runsettings similarity index 100% rename from tests/PolylineAlgorithm.Tests/coverlet.runsettings rename to tests/coverlet.runsettings From 1cc05670567655a6270d306901b061f7a8d33104 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 13:30:23 +0100 Subject: [PATCH 134/352] moved coverlet settings to root, updated test cmd --- .github/workflows/dotnet.yml | 3 +-- tests/coverlet.runsettings => coverlet.runsettings | 0 2 files changed, 1 insertion(+), 2 deletions(-) rename tests/coverlet.runsettings => coverlet.runsettings (100%) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c0939642..786e58c3 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,5 +48,4 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --settings coverlet.runsettings - working-directory: ./tests/ \ No newline at end of file + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --settings coverlet.runsettings \ No newline at end of file diff --git a/tests/coverlet.runsettings b/coverlet.runsettings similarity index 100% rename from tests/coverlet.runsettings rename to coverlet.runsettings From 1726c652ff6dfaaeae4503e0e78204cc875a5111 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 13:38:02 +0100 Subject: [PATCH 135/352] escaped double quotes --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 786e58c3..74ea362c 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,4 +48,4 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --settings coverlet.runsettings \ No newline at end of file + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:\"XPlat Code Coverage\" --settings coverlet.runsettings \ No newline at end of file From 33bf3d3319f0dad22d224b803e3e2385277c2127 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 13:41:48 +0100 Subject: [PATCH 136/352] updated coverlet.settings --- coverlet.runsettings | 3 --- 1 file changed, 3 deletions(-) diff --git a/coverlet.runsettings b/coverlet.runsettings index 58a2d963..e576c188 100644 --- a/coverlet.runsettings +++ b/coverlet.runsettings @@ -5,10 +5,7 @@ json,cobertura,lcov,teamcity,opencover - [coverlet.*.tests?]*,[*]Coverlet.Core* - [coverlet.*]*,[*]Coverlet.Core* Obsolete,GeneratedCodeAttribute,CompilerGeneratedAttribute - **/dir1/class1.cs,**/dir2/*.cs,**/dir3/**/*.cs, false true true From ec0fef4ec4fd39b4a11dce23060c9c27957e6af3 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 13:43:46 +0100 Subject: [PATCH 137/352] fix --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 74ea362c..786e58c3 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,4 +48,4 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:\"XPlat Code Coverage\" --settings coverlet.runsettings \ No newline at end of file + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --settings coverlet.runsettings \ No newline at end of file From 21634cc37585883bc9528b1c45b0861cd4d29828 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 13:47:37 +0100 Subject: [PATCH 138/352] added Microsoft.CodeCoverage package --- tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index ef3223fa..5259f8ea 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -21,6 +21,7 @@ + all From 2c5de2e3ed09db82bd83d32782818aa8632449c3 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 13:52:43 +0100 Subject: [PATCH 139/352] trial and fail --- .github/workflows/dotnet.yml | 2 +- coverlet.runsettings | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 786e58c3..1b18f9d2 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,4 +48,4 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --settings coverlet.runsettings \ No newline at end of file + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:"Code Coverage" --settings coverlet.runsettings \ No newline at end of file diff --git a/coverlet.runsettings b/coverlet.runsettings index e576c188..8443738e 100644 --- a/coverlet.runsettings +++ b/coverlet.runsettings @@ -2,7 +2,7 @@ - + json,cobertura,lcov,teamcity,opencover Obsolete,GeneratedCodeAttribute,CompilerGeneratedAttribute From 402f1405273074a9b2896b70186a3216b0124043 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 13:57:29 +0100 Subject: [PATCH 140/352] project switched to MSTest.Sdk --- tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index 5259f8ea..b84d7b10 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -1,4 +1,4 @@ - + net9.0 From 2db6ae7650835b4fcc0c4f642f37d39ab0ffc65b Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 14:05:13 +0100 Subject: [PATCH 141/352] fix --- .../PolylineAlgorithm.Tests.csproj | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index b84d7b10..1a94a9f0 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -1,4 +1,4 @@ - + net9.0 @@ -11,6 +11,7 @@ false true + Default @@ -20,21 +21,6 @@ false - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - From c1692fb3f9acbb07431f35127a3bd1c54f6f0dd6 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 14:08:15 +0100 Subject: [PATCH 142/352] added package references --- .../PolylineAlgorithm.Tests.csproj | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index 1a94a9f0..cdd41fa9 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -21,6 +21,17 @@ false + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + From 11bbabbaa1341a1def3433da3486c64f46ad81e2 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 14:16:15 +0100 Subject: [PATCH 143/352] fix --- tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index cdd41fa9..a3bc3981 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -30,6 +30,7 @@ + From f12c97b873c24c860d0bb4b919e530aaf85e9a0b Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 14:17:29 +0100 Subject: [PATCH 144/352] simplified nuget references --- .../PolylineAlgorithm.Tests.csproj | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index a3bc3981..f124a078 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -22,14 +22,8 @@ + - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - From a15da2b981512ecb2ab595ec6306407ac05fa71e Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 14:19:30 +0100 Subject: [PATCH 145/352] test --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 1b18f9d2..2bde2b04 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,4 +48,4 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:"Code Coverage" --settings coverlet.runsettings \ No newline at end of file + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:"Code Coverage" \ No newline at end of file From 1771e294cc18719077510ad90eeebff0b3d335d3 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 14:23:02 +0100 Subject: [PATCH 146/352] fix --- tests/Directory.Build.targets | 5 +++++ tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 tests/Directory.Build.targets diff --git a/tests/Directory.Build.targets b/tests/Directory.Build.targets new file mode 100644 index 00000000..d3cba0a3 --- /dev/null +++ b/tests/Directory.Build.targets @@ -0,0 +1,5 @@ + + + true + + \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index f124a078..00fc8846 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -23,7 +23,6 @@ - From 42c94d2df8018bcfca7adb14620ef20f89aedc25 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 14:31:02 +0100 Subject: [PATCH 147/352] fix --- tests/Directory.Build.targets | 5 ----- tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj | 2 ++ 2 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 tests/Directory.Build.targets diff --git a/tests/Directory.Build.targets b/tests/Directory.Build.targets deleted file mode 100644 index d3cba0a3..00000000 --- a/tests/Directory.Build.targets +++ /dev/null @@ -1,5 +0,0 @@ - - - true - - \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index 00fc8846..721262ab 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -11,7 +11,9 @@ false true + true Default + exe From d04e35603fa1c0a322356cf0c20f990267efc26e Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 14:34:23 +0100 Subject: [PATCH 148/352] fix --- .github/workflows/dotnet.yml | 2 +- tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 2bde2b04..945108fe 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,4 +48,4 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --collect:"Code Coverage" \ No newline at end of file + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index 721262ab..5ca58777 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -1,4 +1,4 @@ - + net9.0 From 9ea52abdf4f5893ef47f4a35f23d5e767163bee5 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 14:35:14 +0100 Subject: [PATCH 149/352] fix --- .../PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index 5ca58777..0cc19862 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -1,4 +1,4 @@ - + net9.0 @@ -23,11 +23,6 @@ false - - - - - From 5d0be302752975437a34ebaff61792b2a08b2c06 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 14:40:24 +0100 Subject: [PATCH 150/352] fix --- tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index 0cc19862..5bc5c47e 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -12,6 +12,7 @@ false true true + false Default exe From 0999e7ea6286c3760622f3d1bbb06397e8dcb3ff Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 14:45:41 +0100 Subject: [PATCH 151/352] test --- .github/workflows/dotnet.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 945108fe..e23fefee 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,4 +48,10 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal \ No newline at end of file + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --results-directory TestResults + - name: Upload + uses: actions/upload-artifact@v4 + with: + name: test-results + path: | + **/TestResults/* \ No newline at end of file From 78e32e2123f77d5fcd41e251d06517bbc0ebeafc Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 14:50:05 +0100 Subject: [PATCH 152/352] fix --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index e23fefee..54cc9233 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,7 +48,7 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --results-directory TestResults + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --logger trx --results-directory TestResults - name: Upload uses: actions/upload-artifact@v4 with: From eb72b635b4b3cbbbc2f681ce61a8452c20d65d13 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 15:00:33 +0100 Subject: [PATCH 153/352] test --- .github/workflows/dotnet.yml | 2 +- coverlet.runsettings | 19 ------------------- .../PolylineAlgorithm.Tests.csproj | 8 +++++--- 3 files changed, 6 insertions(+), 23 deletions(-) delete mode 100644 coverlet.runsettings diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 54cc9233..b5144d75 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,7 +48,7 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --logger trx --results-directory TestResults + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --logger trx --coverage --results-directory TestResults - name: Upload uses: actions/upload-artifact@v4 with: diff --git a/coverlet.runsettings b/coverlet.runsettings deleted file mode 100644 index 8443738e..00000000 --- a/coverlet.runsettings +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - json,cobertura,lcov,teamcity,opencover - Obsolete,GeneratedCodeAttribute,CompilerGeneratedAttribute - false - true - true - true - false - MissingAll,MissingAny,None - - - - - \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index 5bc5c47e..bc83e8f0 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -11,10 +11,12 @@ false true - true - false Default - exe + + + + true + true From cca5d763ddaf4848de570506f51ea3b27fc3671c Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 15:02:49 +0100 Subject: [PATCH 154/352] coverage arg --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b5144d75..9df146fa 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,7 +48,7 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --logger trx --coverage --results-directory TestResults + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --logger trx --coverage "Code Coverage" --results-directory TestResults - name: Upload uses: actions/upload-artifact@v4 with: From e84689257f8f5b22a62d871ed7140622a37cd1fa Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 15:06:40 +0100 Subject: [PATCH 155/352] fix --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 9df146fa..b053173c 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,7 +48,7 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --logger trx --coverage "Code Coverage" --results-directory TestResults + run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --logger trx --collect:"Code Coverage" --results-directory TestResults - name: Upload uses: actions/upload-artifact@v4 with: From 63c141fee99a3b0901adff2d3ae487bfe856926a Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 15:28:59 +0100 Subject: [PATCH 156/352] temp commit --- src/PolylineAlgorithm/IPolylineDecoder.cs | 21 +++++ src/PolylineAlgorithm/IPolylineEncoder.cs | 21 +++++ src/PolylineAlgorithm/Internal/Constants.cs | 42 +++++----- .../Internal/PolylineReader.cs | 2 +- .../InvalidCoordinateException.cs | 27 +++++++ .../MalformedPolylineException.cs | 33 ++++++++ src/PolylineAlgorithm/PolylineEncoder.cs | 6 +- .../Validation/CoordinateRange.cs | 77 +++++++++++++++++++ .../Validation/CoordinateValidator.cs | 41 ++++++++++ .../GlobalSuppressions.cs | 2 +- tests/PolylineAlgorithm.Tests/GlobalUsings.cs | 5 +- .../Internal/Category.cs | 4 + .../{ => Internal}/Defaults.cs | 27 ++++--- .../InvalidCoordinateExceptionTest.cs | 36 +++++++++ .../MalformedPolylineExceptionTest.cs | 29 +++++++ .../PolylineAlgorithm.Tests.csproj | 6 +- .../PolylineDecoderTest.cs | 42 +++++++--- .../PolylineEncoderTest.cs | 59 ++++++++++---- .../Properties/AssemblyInfo.cs | 5 +- 19 files changed, 417 insertions(+), 68 deletions(-) create mode 100644 src/PolylineAlgorithm/IPolylineDecoder.cs create mode 100644 src/PolylineAlgorithm/IPolylineEncoder.cs create mode 100644 src/PolylineAlgorithm/InvalidCoordinateException.cs create mode 100644 src/PolylineAlgorithm/MalformedPolylineException.cs create mode 100644 src/PolylineAlgorithm/Validation/CoordinateRange.cs create mode 100644 src/PolylineAlgorithm/Validation/CoordinateValidator.cs create mode 100644 tests/PolylineAlgorithm.Tests/Internal/Category.cs rename tests/PolylineAlgorithm.Tests/{ => Internal}/Defaults.cs (75%) create mode 100644 tests/PolylineAlgorithm.Tests/InvalidCoordinateExceptionTest.cs create mode 100644 tests/PolylineAlgorithm.Tests/MalformedPolylineExceptionTest.cs diff --git a/src/PolylineAlgorithm/IPolylineDecoder.cs b/src/PolylineAlgorithm/IPolylineDecoder.cs new file mode 100644 index 00000000..b280b63b --- /dev/null +++ b/src/PolylineAlgorithm/IPolylineDecoder.cs @@ -0,0 +1,21 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; + +using System; +using System.Collections.Generic; + +/// +/// Defines method to decode a polyline. +/// +public interface IPolylineDecoder { + /// + /// Converts an encoded polyline to a set of coordinates. + /// + /// An encoded polyline to decode. + /// A set of coordinates. + IEnumerable Decode(ref readonly ReadOnlySpan polyline); +} \ No newline at end of file diff --git a/src/PolylineAlgorithm/IPolylineEncoder.cs b/src/PolylineAlgorithm/IPolylineEncoder.cs new file mode 100644 index 00000000..ed6a024d --- /dev/null +++ b/src/PolylineAlgorithm/IPolylineEncoder.cs @@ -0,0 +1,21 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; + +using System; +using System.Collections.Generic; + +/// +/// Defines method to encode a set of coordinates. +/// +public interface IPolylineEncoder { + /// + /// Converts a set of coordinates to an encoded polyline. + /// + /// A set of coordinates to encode. + /// An encoded polyline. + ReadOnlySpan Encode(IEnumerable coordinates); +} \ No newline at end of file diff --git a/src/PolylineAlgorithm/Internal/Constants.cs b/src/PolylineAlgorithm/Internal/Constants.cs index c487eb7b..f8babb76 100644 --- a/src/PolylineAlgorithm/Internal/Constants.cs +++ b/src/PolylineAlgorithm/Internal/Constants.cs @@ -38,29 +38,29 @@ internal static class ASCII { public const int UnitSeparator = 31; } - ///// - ///// Defines coordinates constant values - ///// - //internal static class Coordinate { - // /// - // /// Defines the maximum value for latitude - // /// - // public const int MaxLatitude = 90; + /// + /// Defines coordinates constant values + /// + internal static class Coordinate { + /// + /// Defines the maximum value for latitude + /// + public const int MaxLatitude = 90; - // /// - // /// Defines the maximum value for longitude - // /// - // public const int MaxLongitude = 180; + /// + /// Defines the maximum value for longitude + /// + public const int MaxLongitude = 180; - // /// - // /// Defines the maximum value for latitude - // /// - // public const int MinLatitude = -MaxLatitude; + /// + /// Defines the maximum value for latitude + /// + public const int MinLatitude = -MaxLatitude; - // /// - // /// Defines the maximum value for longitude - // /// - // public const int MinLongitude = -MaxLongitude; - //} + /// + /// Defines the maximum value for longitude + /// + public const int MinLongitude = -MaxLongitude; + } } } diff --git a/src/PolylineAlgorithm/Internal/PolylineReader.cs b/src/PolylineAlgorithm/Internal/PolylineReader.cs index 27852080..2639b317 100644 --- a/src/PolylineAlgorithm/Internal/PolylineReader.cs +++ b/src/PolylineAlgorithm/Internal/PolylineReader.cs @@ -26,7 +26,7 @@ public Coordinate Read() { Coordinate coordinate = new(Precise(ref latitude), Precise(ref longitude)); if (!coordinate.IsValid) { - throw new InvalidOperationException(); + throw new InvalidCoordinateException(coordinate); } return coordinate; diff --git a/src/PolylineAlgorithm/InvalidCoordinateException.cs b/src/PolylineAlgorithm/InvalidCoordinateException.cs new file mode 100644 index 00000000..601521c4 --- /dev/null +++ b/src/PolylineAlgorithm/InvalidCoordinateException.cs @@ -0,0 +1,27 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; + +using PolylineAlgorithm.Internal; +using System.Diagnostics.CodeAnalysis; + +/// +/// Represents error that is caused by invalid coordinate. +/// +[SuppressMessage("Design", "CA1032:Implement standard exception constructors", Justification = "Main purpose is to report coordinate that is invalid, thus we have to have only one construtor.")] +public sealed class InvalidCoordinateException : Exception { + public InvalidCoordinateException(Coordinate coordinate, Exception? innerException = null) + : base(string.Format(ExceptionMessageResource.CoordinateValidationExceptionCoordinateIsOutOfRangeErrorMessageFormat, coordinate.Latitude, coordinate.Longitude), + innerException) + { + Coordinate = coordinate; + } + + /// + /// Coordinate that caused the exception. + /// + public Coordinate Coordinate { get; } +} diff --git a/src/PolylineAlgorithm/MalformedPolylineException.cs b/src/PolylineAlgorithm/MalformedPolylineException.cs new file mode 100644 index 00000000..0231a3a8 --- /dev/null +++ b/src/PolylineAlgorithm/MalformedPolylineException.cs @@ -0,0 +1,33 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm; + +using PolylineAlgorithm.Internal; +using System; +using System.Diagnostics.CodeAnalysis; + +/// +/// Represents error that occurs during polyline encoding. +/// +[SuppressMessage("Design", "CA1032:Implement standard exception constructors", Justification = "Main purpose is to report position in which failure occurs, thus we have to have only one construtor.")] +public sealed class MalformedPolylineException : Exception { + /// + /// Initializes an instance + /// + /// + /// + public MalformedPolylineException(int position, Exception? innerException = null) + : base(string.Format(ExceptionMessageResource.PolylineStringIsMalformed, position), + innerException) + { + Position = position; + } + + /// + /// Position in polyline string at which error occurs. + /// + public int Position { get; } +} \ No newline at end of file diff --git a/src/PolylineAlgorithm/PolylineEncoder.cs b/src/PolylineAlgorithm/PolylineEncoder.cs index 9c23cd48..3760d957 100644 --- a/src/PolylineAlgorithm/PolylineEncoder.cs +++ b/src/PolylineAlgorithm/PolylineEncoder.cs @@ -33,12 +33,16 @@ public ReadOnlySpan Encode(IEnumerable coordinates) { } // Initializing local variables - int capacity = count * 11; + int capacity = count * 12; Span buffer = new char[capacity]; PolylineWriter writer = new(in buffer); // Looping over coordinates and building encoded result foreach (var coordinate in coordinates) { + if(!coordinate.IsValid) { + throw new InvalidCoordinateException(coordinate); + } + writer.Write(in coordinate); } diff --git a/src/PolylineAlgorithm/Validation/CoordinateRange.cs b/src/PolylineAlgorithm/Validation/CoordinateRange.cs new file mode 100644 index 00000000..5e8f6788 --- /dev/null +++ b/src/PolylineAlgorithm/Validation/CoordinateRange.cs @@ -0,0 +1,77 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Validation; + +using PolylineAlgorithm.Internal; +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +/// +/// Represents a range within coordinate value, latitude or longitude, is considered valid. +/// +[DebuggerDisplay(@"{ Min: {Min}, Max: {Max} }")] +[StructLayout(LayoutKind.Sequential, Pack = 8, Size = 16)] +public readonly struct CoordinateRange : IEquatable { + public CoordinateRange(double min, double max) { + if (min >= max) { + throw new ArgumentException(string.Format("", min.ToString(), max.ToString()), paramName: nameof(min)); + } + + Min = min; + Max = max; + } + + /// + /// Represents inclusive minimal value of the range. + /// + public readonly double Min { get; } + + /// + /// Represents inclusive maximal value of the range. + /// + public readonly double Max { get; } + + /// + /// Indicates whether the is within the range. + /// + /// A value to be validated is in range. + /// if is within the range; otherwise, . + public bool IsInRange(double value) => value >= Min && value <= Max; + + /// + /// Returns the formatted string respresentation of this instance. + /// + /// The formatted string respresentation of this instance. + /// { Min: [double], Max: [double] } + public override string ToString() { + return $"{{ {nameof(Min)}: {Min}, {nameof(Max)}: {Max} }}"; + } + + /// + public override bool Equals(object? obj) { + return obj is CoordinateRange range && Equals(range); + } + + /// + public bool Equals(CoordinateRange other) { + return Min == other.Min && + Max == other.Max; + } + + /// + public override int GetHashCode() { + return HashCode.Combine(Min, Max); + } + + public static bool operator ==(CoordinateRange left, CoordinateRange right) { + return left.Equals(right); + } + + public static bool operator !=(CoordinateRange left, CoordinateRange right) { + return !(left == right); + } +} diff --git a/src/PolylineAlgorithm/Validation/CoordinateValidator.cs b/src/PolylineAlgorithm/Validation/CoordinateValidator.cs new file mode 100644 index 00000000..c91111bf --- /dev/null +++ b/src/PolylineAlgorithm/Validation/CoordinateValidator.cs @@ -0,0 +1,41 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Validation; + +using PolylineAlgorithm.Internal; +using System.Diagnostics.CodeAnalysis; + +/// +/// +/// +public sealed class CoordinateValidator { + /// + /// Represents default coordinate validator. This field is read-only. + /// + /// Validates latitude between -90 and 90; longitude between -180 and 180. + [SuppressMessage("Usage", "CA2211:Non-constant fields should not be visible", Justification = "We just want to deal with it this way.")] + public static readonly CoordinateValidator Default = new(new CoordinateRange(Constants.Coordinate.MinLatitude, Constants.Coordinate.MaxLatitude), new CoordinateRange(Constants.Coordinate.MinLongitude, Constants.Coordinate.MaxLongitude)); + + /// + /// Initializes an instance of coordinate validator. + /// + /// A latitude range. + /// A longitude range. + public CoordinateValidator(CoordinateRange latitudeRange, CoordinateRange longitudeRange) { + Latitude = latitudeRange; + Longitude = longitudeRange; + } + + /// + /// A latitude validation range. + /// + public CoordinateRange Latitude { get; } + + /// + /// A longitude validation range. + /// + public CoordinateRange Longitude { get; } +} diff --git a/tests/PolylineAlgorithm.Tests/GlobalSuppressions.cs b/tests/PolylineAlgorithm.Tests/GlobalSuppressions.cs index 0b97243b..b1c53da8 100644 --- a/tests/PolylineAlgorithm.Tests/GlobalSuppressions.cs +++ b/tests/PolylineAlgorithm.Tests/GlobalSuppressions.cs @@ -5,4 +5,4 @@ using System.Diagnostics.CodeAnalysis; -[assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Applies only to production code. Test assemblies are not production code.")] +[assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Ignore in test asemblies.")] diff --git a/tests/PolylineAlgorithm.Tests/GlobalUsings.cs b/tests/PolylineAlgorithm.Tests/GlobalUsings.cs index 8280b9af..bdba132f 100644 --- a/tests/PolylineAlgorithm.Tests/GlobalUsings.cs +++ b/tests/PolylineAlgorithm.Tests/GlobalUsings.cs @@ -3,7 +3,4 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -global using Microsoft.VisualStudio.TestTools.UnitTesting; -global using System; -global using System.Collections.Generic; -global using System.Linq; \ No newline at end of file +global using Microsoft.VisualStudio.TestTools.UnitTesting; \ No newline at end of file diff --git a/tests/PolylineAlgorithm.Tests/Internal/Category.cs b/tests/PolylineAlgorithm.Tests/Internal/Category.cs new file mode 100644 index 00000000..dd6daccc --- /dev/null +++ b/tests/PolylineAlgorithm.Tests/Internal/Category.cs @@ -0,0 +1,4 @@ +namespace PolylineAlgorithm.Tests.Internal; +internal static class Category { + public const string Unit = nameof(Unit); +} diff --git a/tests/PolylineAlgorithm.Tests/Defaults.cs b/tests/PolylineAlgorithm.Tests/Internal/Defaults.cs similarity index 75% rename from tests/PolylineAlgorithm.Tests/Defaults.cs rename to tests/PolylineAlgorithm.Tests/Internal/Defaults.cs index 91d2a4c1..38726128 100644 --- a/tests/PolylineAlgorithm.Tests/Defaults.cs +++ b/tests/PolylineAlgorithm.Tests/Internal/Defaults.cs @@ -3,15 +3,16 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace PolylineAlgorithm.Tests; +namespace PolylineAlgorithm.Tests.Internal; -using System; using System.Collections.Generic; /// /// Defines default values and objects used for testing purposes /// -public static class Defaults { +internal static class Defaults { + internal static readonly Random R = new(DateTime.Now.Millisecond); + /// /// Defines default decoded values and objects udÅ›ed for testing purposes /// @@ -24,12 +25,12 @@ public static class Coordinates { /// /// Defines range of invalid coordinates. Equals to decoded /// - //public static readonly IEnumerable Invalid = [ - // new(149.47383, 259.06250), - // new(-158.37407, 225.31250), - // new(152.99363, -220.93750), - // new(-144.49024, -274.37500) - //]; + public static readonly IEnumerable Invalid = [ + new(149.47383, 259.06250), + new(-158.37407, 225.31250), + new(152.99363, -220.93750), + new(-144.49024, -274.37500) + ]; /// /// Defines range of valid coordinates. Equals to decoded @@ -61,4 +62,12 @@ public static class Polyline { /// public static readonly string Valid = "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; } + + public static class MalformedPolylineException { + public static readonly int Position = R.Next(); + } + + public static class InvalidCoordinateException { + public static readonly Coordinate Coordinate = new(R.NextDouble(), R.NextDouble()); + } } diff --git a/tests/PolylineAlgorithm.Tests/InvalidCoordinateExceptionTest.cs b/tests/PolylineAlgorithm.Tests/InvalidCoordinateExceptionTest.cs new file mode 100644 index 00000000..a8cff501 --- /dev/null +++ b/tests/PolylineAlgorithm.Tests/InvalidCoordinateExceptionTest.cs @@ -0,0 +1,36 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Tests; + +using PolylineAlgorithm.Tests.Internal; + +/// +/// Performs tests for type. +/// +[TestClass] +public class InvalidCoordinateExceptionTest { + + /// + /// Method is testing constructor. and are passed as arguments. + /// + /// Expected: equals passed argument, + /// equals passed argument, + /// and in not , empty -or- whitespace. + [TestMethod] + public void Constructor_Ok() { + // Arrange + var coordinate = Defaults.InvalidCoordinateException.Coordinate; + var innerException = new Exception(); + + // Act + InvalidCoordinateException result = new(coordinate, innerException); + + // Assert + Assert.AreEqual(coordinate, result.Coordinate); + Assert.AreEqual(innerException, result.InnerException); + Assert.IsFalse(string.IsNullOrWhiteSpace(result.Message)); + } +} diff --git a/tests/PolylineAlgorithm.Tests/MalformedPolylineExceptionTest.cs b/tests/PolylineAlgorithm.Tests/MalformedPolylineExceptionTest.cs new file mode 100644 index 00000000..b2f119bc --- /dev/null +++ b/tests/PolylineAlgorithm.Tests/MalformedPolylineExceptionTest.cs @@ -0,0 +1,29 @@ +// +// Copyright (c) Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace PolylineAlgorithm.Tests; + +using PolylineAlgorithm.Tests.Internal; + +/// +/// Defines tests for type. +/// +[TestClass] +public class MalformedPolylineExceptionTest { + [TestMethod] + public void Constructor_Ok() { + // Arrange + var position = Defaults.MalformedPolylineException.Position; + var innerException = new Exception(); + + // Act + MalformedPolylineException exception = new(position, innerException); + + // Assert + Assert.AreEqual(Defaults.MalformedPolylineException.Position, exception.Position); + Assert.IsFalse(string.IsNullOrWhiteSpace(exception.Message)); + Assert.IsNotNull(exception.InnerException); + } +} diff --git a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj index bc83e8f0..a3d8adb5 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj +++ b/tests/PolylineAlgorithm.Tests/PolylineAlgorithm.Tests.csproj @@ -1,4 +1,4 @@ - + net9.0 @@ -26,6 +26,10 @@ false + + + + diff --git a/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs b/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs index aacd2520..47090b0f 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs +++ b/tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs @@ -6,40 +6,58 @@ namespace PolylineAlgorithm.Tests; using PolylineAlgorithm; +using PolylineAlgorithm.Tests.Internal; /// -/// Defines the +/// Defines tests for type. /// [TestClass] -[TestCategory(nameof(PolylineDecoder))] public class PolylineDecoderTest { public PolylineDecoder Decoder = new PolylineDecoder(); /// - /// Method is testing method. Empty [] is passed as parameter. - /// Expected result is . + /// Method is testing method. Empty is passed as an argument. /// + /// Expected to throw . + [TestMethod] + public void Decode_EmptyInput_ThrowsException() { + // Arrange + ReadOnlyMemory empty = Defaults.Polyline.Empty.AsMemory(); + + // Act + void Execute(ReadOnlySpan value) => Decoder.Decode(in value); + + // Assert + Assert.ThrowsException(() => Execute(empty.Span)); + } + + /// + /// Method is testing method. containing invalid polyline is passed as an argument. + /// + /// Expected to throw . [TestMethod] - [ExpectedException(typeof(InvalidOperationException))] public void Decode_InvalidInput_ThrowsException() { // Arrange - ReadOnlySpan invalidPolylineCharArray = Defaults.Polyline.Invalid; + ReadOnlyMemory invalid = Defaults.Polyline.Invalid.AsMemory(); // Act - var result = Decoder.Decode(in invalidPolylineCharArray); + void Execute(ReadOnlySpan value) => Decoder.Decode(in value); + + // Assert + Assert.ThrowsException(() => Execute(invalid.Span)); } /// - /// Method is testing method. [] with valid coordinates is passed as parameter. - /// Expected result is . + /// Method is testing method. containing valid polyline is passed as an argument. /// + /// Expected result to equal .. [TestMethod] - public void Decode_ValidInput_AreEquivalent() { + public void Decode_ValidInput_Ok() { // Arrange - ReadOnlySpan validPolylineCharArray = Defaults.Polyline.Valid; + ReadOnlySpan valid = Defaults.Polyline.Valid; // Act - var result = Decoder.Decode(in validPolylineCharArray); + var result = Decoder.Decode(in valid); // Assert CollectionAssert.AreEqual(Defaults.Coordinates.Valid.ToArray(), result.ToArray()); diff --git a/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs b/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs index 8c833a6f..faeaf624 100644 --- a/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs +++ b/tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs @@ -4,25 +4,49 @@ // namespace PolylineAlgorithm.Tests; + +using PolylineAlgorithm.Tests.Internal; + /// -/// Defines the +/// Defines tests for type. /// [TestClass] -[TestCategory(nameof(PolylineEncoder))] public class PolylineEncoderTest { - public PolylineEncoder Encoder = new PolylineEncoder(); /// - /// Method is testing method. Empty is passed as parameter. + /// Subject under test. + /// + public PolylineEncoder Encoder = new(); + + /// + /// Method is testing method. is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Encode_NullInput_ThrowsException() { + // Arrange + IEnumerable @null = (IEnumerable)null!; + + // Act + void EncodeNullCoordinates() { + Encoder.Encode(@null); + } + + // Assert + Assert.ThrowsException(() => EncodeNullCoordinates()); + } + + /// + /// Method is testing method. Empty enumeration is passed as parameter. /// Expected result is . /// [TestMethod] public void Encode_EmptyInput_ThrowsException() { // Arrange - var emptyCoordinates = Defaults.Coordinates.Empty; + IEnumerable empty = Defaults.Coordinates.Empty; // Act void EncodeEmptyCoordinates() { - Encoder.Encode(emptyCoordinates); + Encoder.Encode(empty); } // Assert @@ -30,33 +54,34 @@ void EncodeEmptyCoordinates() { } /// - /// Method is testing method. is passed as parameter. - /// Expected result is . + /// Method is testing method. Enumeration containing only invalid values is passed as parameter. + /// Expected result is . /// [TestMethod] - public void Encode_NullInput_ThrowsException() { + public void Encode_InvalidInput_ThrowsException() { // Arrange - var nullCoordinates = (IEnumerable)null!; + IEnumerable invalid = Defaults.Coordinates.Invalid; // Act - void EncodeNullCoordinates() { - Encoder.Encode(nullCoordinates); + void EncodeEmptyCoordinates() { + Encoder.Encode(invalid); } // Assert - Assert.ThrowsException(() => EncodeNullCoordinates()); + Assert.ThrowsException(() => EncodeEmptyCoordinates()); } /// - /// The Encode_ValidInput + /// Method is testing method. Enumeration containing only valid values is passed as parameter. + /// Expected result is result and are equal. /// [TestMethod] - public void Encode_ValidInput_AreEqual() { + public void Encode_ValidInput_Ok() { // Arrange - var validCoordinates = Defaults.Coordinates.Valid; + IEnumerable valid = Defaults.Coordinates.Valid; // Act - var result = Encoder.Encode(validCoordinates); + var result = Encoder.Encode(valid); // Assert Assert.AreEqual(Defaults.Polyline.Valid, result.ToString()); diff --git a/tests/PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs b/tests/PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs index aae125e3..91d8cbeb 100644 --- a/tests/PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs +++ b/tests/PolylineAlgorithm.Tests/Properties/AssemblyInfo.cs @@ -3,4 +3,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] \ No newline at end of file +using PolylineAlgorithm.Tests.Internal; + +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] +[assembly: TestCategory(Category.Unit)] \ No newline at end of file From 9136940eb5f046e1a9819f23afaeddd6352d0b78 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 15:32:01 +0100 Subject: [PATCH 157/352] wooohhoooo --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b053173c..9b9705bf 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,7 +48,7 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test --no-restore --no-build --configuration Release --verbosity normal --logger trx --collect:"Code Coverage" --results-directory TestResults + run: dotnet test./tests/**/*Tests.csproj --no-restore --no-build --configuration Release --verbosity normal --logger trx --collect:"Code Coverage" --results-directory TestResults - name: Upload uses: actions/upload-artifact@v4 with: From eece0f0fbbcdda061a904ceb8e036eb46b0718ce Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 15:33:32 +0100 Subject: [PATCH 158/352] woohooo2 --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 9b9705bf..dabb9cce 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,7 +48,7 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test./tests/**/*Tests.csproj --no-restore --no-build --configuration Release --verbosity normal --logger trx --collect:"Code Coverage" --results-directory TestResults + run: dotnet test ./tests/**/*Tests.csproj --no-restore --no-build --configuration Release --verbosity normal --logger trx --collect:"Code Coverage" --results-directory TestResults - name: Upload uses: actions/upload-artifact@v4 with: From bb5be58784fb03310e6c6abf786e53d03702688a Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 15:35:41 +0100 Subject: [PATCH 159/352] wohhoo3 --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index dabb9cce..bf18cee0 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -48,7 +48,7 @@ jobs: path: . merge-multiple: true - name: Test - run: dotnet test ./tests/**/*Tests.csproj --no-restore --no-build --configuration Release --verbosity normal --logger trx --collect:"Code Coverage" --results-directory TestResults + run: dotnet test ./tests/**/*Tests.csproj --no-restore --configuration Release --verbosity normal --logger trx --collect:"Code Coverage" --results-directory TestResults - name: Upload uses: actions/upload-artifact@v4 with: From 845187100a7f3092ddf58aae84bb96f7493c158e Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 15:38:18 +0100 Subject: [PATCH 160/352] wooohooo454 --- .github/workflows/dotnet.yml | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index bf18cee0..e5fef551 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -22,13 +22,6 @@ jobs: run: dotnet restore - name: Build run: dotnet build --no-restore --configuration Release - - name: Upload - uses: actions/upload-artifact@v4 - with: - name: build - path: | - **/bin/* - **/obj/* test: name: Test with MsTest @@ -42,13 +35,8 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: 9.x - - uses: actions/download-artifact@v4 - with: - name: build - path: . - merge-multiple: true - name: Test - run: dotnet test ./tests/**/*Tests.csproj --no-restore --configuration Release --verbosity normal --logger trx --collect:"Code Coverage" --results-directory TestResults + run: dotnet test ./tests/**/*Tests.csproj --configuration Release --verbosity normal --logger trx --collect:"Code Coverage" --results-directory TestResults - name: Upload uses: actions/upload-artifact@v4 with: From b1dfe6b50f6598f8077e0fedefa65dd08653f6e8 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 15:41:49 +0100 Subject: [PATCH 161/352] woohooo6 --- .github/workflows/dotnet.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index e5fef551..cda8cd81 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -21,7 +21,14 @@ jobs: - name: Restore run: dotnet restore - name: Build - run: dotnet build --no-restore --configuration Release + run: dotnet build ./src/**/*.csproj --no-restore --configuration Release + - name: Upload + uses: actions/upload-artifact@v4 + with: + name: build + path: | + src/**/bin/* + src/**/obj/* test: name: Test with MsTest From 6c98e9ac3209b314d23e44202660c1c5bafd7690 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 15:46:12 +0100 Subject: [PATCH 162/352] added interface for enc and dec types --- src/PolylineAlgorithm/PolylineDecoder.cs | 2 +- src/PolylineAlgorithm/PolylineEncoder.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PolylineAlgorithm/PolylineDecoder.cs b/src/PolylineAlgorithm/PolylineDecoder.cs index fd1fd2c4..1bb83ef8 100644 --- a/src/PolylineAlgorithm/PolylineDecoder.cs +++ b/src/PolylineAlgorithm/PolylineDecoder.cs @@ -9,7 +9,7 @@ namespace PolylineAlgorithm; /// /// A coordinate validator. -public class PolylineDecoder { +public class PolylineDecoder : IPolylineDecoder { /// /// Thrown when argument is null -or- empty. diff --git a/src/PolylineAlgorithm/PolylineEncoder.cs b/src/PolylineAlgorithm/PolylineEncoder.cs index 3760d957..ebfddd81 100644 --- a/src/PolylineAlgorithm/PolylineEncoder.cs +++ b/src/PolylineAlgorithm/PolylineEncoder.cs @@ -12,7 +12,7 @@ namespace PolylineAlgorithm; /// /// Performs polyline algorithm decoding and encoding /// -public class PolylineEncoder { +public class PolylineEncoder : IPolylineEncoder { /// /// Encodes coordinates to polyline representation /// From c170ace85edc765a7dd510bcbcaa09627f918f05 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 16:49:08 +0100 Subject: [PATCH 163/352] lets try it --- .github/workflows/dotnet.yml | 4 +-- unit-test.runsettings | 50 ++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 unit-test.runsettings diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index cda8cd81..43fe3888 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -43,10 +43,10 @@ jobs: with: dotnet-version: 9.x - name: Test - run: dotnet test ./tests/**/*Tests.csproj --configuration Release --verbosity normal --logger trx --collect:"Code Coverage" --results-directory TestResults + run: dotnet test ./tests/**/*Tests.csproj --configuration Release --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results - name: Upload uses: actions/upload-artifact@v4 with: name: test-results path: | - **/TestResults/* \ No newline at end of file + **/test-results/* \ No newline at end of file diff --git a/unit-test.runsettings b/unit-test.runsettings new file mode 100644 index 00000000..7d24c7e5 --- /dev/null +++ b/unit-test.runsettings @@ -0,0 +1,50 @@ + + + + + + + + + coverage + + + + .*\.dll$ + + + + + + + + ^System\.Diagnostics\.DebuggerHiddenAttribute$ + ^System\.Diagnostics\.DebuggerNonUserCodeAttribute$ + ^System\.CodeDom\.Compiler\.GeneratedCodeAttribute$ + ^System\.Diagnostics\.CodeAnalysis\.ExcludeFromCodeCoverageAttribute$ + + + + + + + True + + True + + True + + False + + True + + True + + True + + + + + + + \ No newline at end of file From 9f04b48af7fbea3556d6e803665b36481be33e4d Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 18:23:37 +0100 Subject: [PATCH 164/352] test --- .github/templates/build.yml | 37 ++++++++++++++++++++++++++++++++++++ .github/workflows/dotnet.yml | 3 ++- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 .github/templates/build.yml diff --git a/.github/templates/build.yml b/.github/templates/build.yml new file mode 100644 index 00000000..b653e0b9 --- /dev/null +++ b/.github/templates/build.yml @@ -0,0 +1,37 @@ +name: 'Build with .NET SDK' +description: 'Build solution or projects with specific version of .NET SDK.' + +inputs: + search-pattern: # Solution(s) or project(s) to build e.g. src/**/*.csproj + description: 'Solution(s) or project(s) to build e.g. src/**/*.csproj' + required: true + default: '**/*.*' + dotnet-version: # .NET version(s) to be installed + description: '.NET version(s) to be installed' + required: false + default: '9.x' + configuration: + description: 'Build Configuration' + required: false + default: 'Release' + platform: + description: 'Build Platform' + required: false + default: 'AnyCPU' + +runs: + using: "composite" + steps: + - name: Install .NET 9 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: $DOTNET_VERSION + - name: Restore + run: dotnet restore + - name: Build + run: dotnet build $SEARCH_PATTERN --no-restore --configuration $CONFIGURATION --platform $PLATFORM + env: + SEARCH_PATTERN: ${{ inputs.search-pattern }} + DOTNET_VERSION: ${{ inputs.dotnet-version }} + CONFIGURATION: ${{ inputs.configuration }} + PLATFORM: ${{ inputs.platform }} \ No newline at end of file diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 43fe3888..b49fa496 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,12 +14,13 @@ jobs: steps: - uses: actions/checkout@v3 + - uses: petesramek/templates/build - name: Install .NET 9 uses: actions/setup-dotnet@v4 with: dotnet-version: 9.x - name: Restore - run: dotnet restore + run: dotnet restore ./src/**/*.csproj - name: Build run: dotnet build ./src/**/*.csproj --no-restore --configuration Release - name: Upload From 6e7d4a29577bb3f60e3198d3e9f076784a839cb5 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 18:26:05 +0100 Subject: [PATCH 165/352] added SHA --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b49fa496..d8be0959 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: petesramek/templates/build + - uses: petesramek/templates/build@9f04b48af7fbea3556d6e803665b36481be33e4d - name: Install .NET 9 uses: actions/setup-dotnet@v4 with: From dcac09bec9e8c1947f1c4993a264b88bdd79d1d8 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 18:27:53 +0100 Subject: [PATCH 166/352] aha --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d8be0959..d7355607 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: petesramek/templates/build@9f04b48af7fbea3556d6e803665b36481be33e4d + - uses: petesramek/polyline-algorithm-csharp/.github/templates/build@9f04b48af7fbea3556d6e803665b36481be33e4d - name: Install .NET 9 uses: actions/setup-dotnet@v4 with: From f66d75b330b2878ff3b6cb017438b8fddb866e96 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 20:22:26 +0100 Subject: [PATCH 167/352] wooohoo --- .github/actions/build-dotnet.yml | 36 +++++++++++++++++++++++++++++++ .github/templates/build.yml | 37 -------------------------------- .github/workflows/dotnet.yml | 18 ++++++++-------- 3 files changed, 45 insertions(+), 46 deletions(-) create mode 100644 .github/actions/build-dotnet.yml delete mode 100644 .github/templates/build.yml diff --git a/.github/actions/build-dotnet.yml b/.github/actions/build-dotnet.yml new file mode 100644 index 00000000..bb2965b8 --- /dev/null +++ b/.github/actions/build-dotnet.yml @@ -0,0 +1,36 @@ +on: + workflow_call: + inputs: + search-pattern: # Solution(s) or project(s) to build e.g. src/**/*.csproj + description: 'Solution(s) or project(s) to build e.g. src/**/*.csproj' + required: false + default: '**/*.*' + dotnet-version: # .NET version(s) to be installed + description: '.NET version(s) to be installed' + required: false + default: '9.x' + configuration: + description: 'Build Configuration' + required: false + default: 'Release' + platform: + description: 'Build Platform' + required: false + default: 'AnyCPU' + +jobs: + build-jon: + steps: + - name: Install .NET 9 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: $DOTNET_VERSION + - name: Restore + run: dotnet restore + - name: Build + run: dotnet build $SEARCH_PATTERN --no-restore --configuration $CONFIGURATION --platform $PLATFORM + env: + SEARCH_PATTERN: ${{ inputs.search-pattern }} + DOTNET_VERSION: ${{ inputs.dotnet-version }} + CONFIGURATION: ${{ inputs.configuration }} + PLATFORM: ${{ inputs.platform }} \ No newline at end of file diff --git a/.github/templates/build.yml b/.github/templates/build.yml deleted file mode 100644 index b653e0b9..00000000 --- a/.github/templates/build.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: 'Build with .NET SDK' -description: 'Build solution or projects with specific version of .NET SDK.' - -inputs: - search-pattern: # Solution(s) or project(s) to build e.g. src/**/*.csproj - description: 'Solution(s) or project(s) to build e.g. src/**/*.csproj' - required: true - default: '**/*.*' - dotnet-version: # .NET version(s) to be installed - description: '.NET version(s) to be installed' - required: false - default: '9.x' - configuration: - description: 'Build Configuration' - required: false - default: 'Release' - platform: - description: 'Build Platform' - required: false - default: 'AnyCPU' - -runs: - using: "composite" - steps: - - name: Install .NET 9 - uses: actions/setup-dotnet@v4 - with: - dotnet-version: $DOTNET_VERSION - - name: Restore - run: dotnet restore - - name: Build - run: dotnet build $SEARCH_PATTERN --no-restore --configuration $CONFIGURATION --platform $PLATFORM - env: - SEARCH_PATTERN: ${{ inputs.search-pattern }} - DOTNET_VERSION: ${{ inputs.dotnet-version }} - CONFIGURATION: ${{ inputs.configuration }} - PLATFORM: ${{ inputs.platform }} \ No newline at end of file diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d7355607..4baa76f4 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,15 +14,15 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: petesramek/polyline-algorithm-csharp/.github/templates/build@9f04b48af7fbea3556d6e803665b36481be33e4d - - name: Install .NET 9 - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 9.x - - name: Restore - run: dotnet restore ./src/**/*.csproj - - name: Build - run: dotnet build ./src/**/*.csproj --no-restore --configuration Release + - uses: ./.github/actions/build-dotnet + # - name: Install .NET 9 + # uses: actions/setup-dotnet@v4 + # with: + # dotnet-version: 9.x + # - name: Restore + # run: dotnet restore ./src/**/*.csproj + # - name: Build + # run: dotnet build ./src/**/*.csproj --no-restore --configuration Release - name: Upload uses: actions/upload-artifact@v4 with: From 576d435d25a82cf05e8e938af4fd98f711b8b9d8 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 20:29:11 +0100 Subject: [PATCH 168/352] whoops --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 4baa76f4..5c423131 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: ./.github/actions/build-dotnet + - uses: ./.github/actions/build-dotnet@feature/v2-implementation # - name: Install .NET 9 # uses: actions/setup-dotnet@v4 # with: From ddd106a3b8546c8b7872c5811b8735fc506d56af Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 20:30:10 +0100 Subject: [PATCH 169/352] saaf --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 5c423131..75f8a1d2 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: ./.github/actions/build-dotnet@feature/v2-implementation + - uses: ./.github/actions/build-dotnet.yml@feature/v2-implementation # - name: Install .NET 9 # uses: actions/setup-dotnet@v4 # with: From 56cacbfb181d866d6aec05fa79e18f4957dba95e Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 20:31:06 +0100 Subject: [PATCH 170/352] zsfasf --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 75f8a1d2..96104405 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: ./.github/actions/build-dotnet.yml@feature/v2-implementation + - uses: ./.github/actions/build-dotnet.yml # - name: Install .NET 9 # uses: actions/setup-dotnet@v4 # with: From 67d46988c49e76bdca1c3d1379f21f545088ed99 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 20:33:52 +0100 Subject: [PATCH 171/352] whoaa --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 96104405..75f8a1d2 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: ./.github/actions/build-dotnet.yml + - uses: ./.github/actions/build-dotnet.yml@feature/v2-implementation # - name: Install .NET 9 # uses: actions/setup-dotnet@v4 # with: From d70bffa21e3530d1d1a4dbd29533894a5c3a9524 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 20:36:11 +0100 Subject: [PATCH 172/352] szdfa --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 75f8a1d2..4beb54dc 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: ./.github/actions/build-dotnet.yml@feature/v2-implementation + - uses: petesramek/polyline-algorithm-csharp/.github/actions/build-dotnet.yml@feature/v2-implementation # - name: Install .NET 9 # uses: actions/setup-dotnet@v4 # with: From cae477ae3c6c0f88da9612380ef1b51559de024f Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 20:47:20 +0100 Subject: [PATCH 173/352] safaes --- .github/workflows/dotnet.yml | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 4beb54dc..f1df23ca 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -8,13 +8,11 @@ on: jobs: build: - name: Build with .NET 9 - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - uses: petesramek/polyline-algorithm-csharp/.github/actions/build-dotnet.yml@feature/v2-implementation + uses: ./.github/actions/build-dotnet.yml + # name: Build with .NET 9 + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v3 # - name: Install .NET 9 # uses: actions/setup-dotnet@v4 # with: @@ -23,13 +21,13 @@ jobs: # run: dotnet restore ./src/**/*.csproj # - name: Build # run: dotnet build ./src/**/*.csproj --no-restore --configuration Release - - name: Upload - uses: actions/upload-artifact@v4 - with: - name: build - path: | - src/**/bin/* - src/**/obj/* + # - name: Upload + # uses: actions/upload-artifact@v4 + # with: + # name: build + # path: | + # src/**/bin/* + # src/**/obj/* test: name: Test with MsTest From 532ead2369e17b44c7b444bf688db80c91976477 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 20:47:59 +0100 Subject: [PATCH 174/352] xvsd --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index f1df23ca..1c29d27d 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -8,7 +8,7 @@ on: jobs: build: - uses: ./.github/actions/build-dotnet.yml + uses: ./.github/actions/build-dotnet.yml@feature/v2-implementation # name: Build with .NET 9 # runs-on: ubuntu-latest # steps: From bd505346597950e685f0df2f7cc8411f3bc58804 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 21:22:22 +0100 Subject: [PATCH 175/352] uups --- .github/workflows/dotnet.yml | 64 ++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 1c29d27d..c2b92259 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -8,26 +8,25 @@ on: jobs: build: - uses: ./.github/actions/build-dotnet.yml@feature/v2-implementation - # name: Build with .NET 9 - # runs-on: ubuntu-latest - # steps: - # - uses: actions/checkout@v3 - # - name: Install .NET 9 - # uses: actions/setup-dotnet@v4 - # with: - # dotnet-version: 9.x - # - name: Restore - # run: dotnet restore ./src/**/*.csproj - # - name: Build - # run: dotnet build ./src/**/*.csproj --no-restore --configuration Release - # - name: Upload - # uses: actions/upload-artifact@v4 - # with: - # name: build - # path: | - # src/**/bin/* - # src/**/obj/* + name: Build with .NET 9 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install .NET 9 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.x + - name: Restore + run: dotnet restore ./src/**/*.csproj + - name: Build + run: dotnet build ./src/**/*.csproj --no-restore --configuration Release + - name: Upload + uses: actions/upload-artifact@v4 + with: + name: build + path: | + src/**/bin/* + src/**/obj/* test: name: Test with MsTest @@ -48,4 +47,27 @@ jobs: with: name: test-results path: | - **/test-results/* \ No newline at end of file + **/test-results/* + + pack: + name: Pack with .NET 9 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install .NET 9 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.x + - name: Download + uses: actions/download-artifact@v4 + with: + name: build + path: . + - name: Pack + run: dotnet pack ./src/**/*.csproj --no-build --no-restore --configuration Release + - name: Upload + uses: actions/upload-artifact@v4 + with: + name: package + path: | + **/*.nupkg From ff683f9432d87a1e9fb138dc2a21a32e6a24998b Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 21:23:37 +0100 Subject: [PATCH 176/352] oasdhw --- .github/workflows/dotnet.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c2b92259..998f8514 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -31,9 +31,7 @@ jobs: test: name: Test with MsTest needs: [build] - runs-on: ubuntu-latest - steps: - uses: actions/checkout@v3 - name: Setup .NET 9 @@ -51,6 +49,7 @@ jobs: pack: name: Pack with .NET 9 + needs: [test] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 From 7119f155af864064a3b41080835c5d7549773094 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 21:23:59 +0100 Subject: [PATCH 177/352] jlkashdqa --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 998f8514..0f0d6c1b 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -63,7 +63,7 @@ jobs: name: build path: . - name: Pack - run: dotnet pack ./src/**/*.csproj --no-build --no-restore --configuration Release + run: dotnet pack ./src/**/*.csproj --no-build --configuration Release - name: Upload uses: actions/upload-artifact@v4 with: From e5f2e1acafe04f01312eea91907bece264fc026f Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 21:30:03 +0100 Subject: [PATCH 178/352] ,jnl --- .github/workflows/dotnet.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 0f0d6c1b..93d6940e 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -61,7 +61,8 @@ jobs: uses: actions/download-artifact@v4 with: name: build - path: . + - name: Display structure of downloaded files + run: ls -R - name: Pack run: dotnet pack ./src/**/*.csproj --no-build --configuration Release - name: Upload From 341afe4802d2ff72ae018508c6a5cfc14371b565 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 21:31:01 +0100 Subject: [PATCH 179/352] zdfsd --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 93d6940e..d385b17a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -25,8 +25,8 @@ jobs: with: name: build path: | - src/**/bin/* - src/**/obj/* + /**/bin/* + /**/obj/* test: name: Test with MsTest From c722381a05e062aa683ffcf16e036927b99f89e7 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 21:37:54 +0100 Subject: [PATCH 180/352] asafd --- .github/actions/build-dotnet.yml | 36 -------------------------------- .github/workflows/dotnet.yml | 6 ++---- 2 files changed, 2 insertions(+), 40 deletions(-) delete mode 100644 .github/actions/build-dotnet.yml diff --git a/.github/actions/build-dotnet.yml b/.github/actions/build-dotnet.yml deleted file mode 100644 index bb2965b8..00000000 --- a/.github/actions/build-dotnet.yml +++ /dev/null @@ -1,36 +0,0 @@ -on: - workflow_call: - inputs: - search-pattern: # Solution(s) or project(s) to build e.g. src/**/*.csproj - description: 'Solution(s) or project(s) to build e.g. src/**/*.csproj' - required: false - default: '**/*.*' - dotnet-version: # .NET version(s) to be installed - description: '.NET version(s) to be installed' - required: false - default: '9.x' - configuration: - description: 'Build Configuration' - required: false - default: 'Release' - platform: - description: 'Build Platform' - required: false - default: 'AnyCPU' - -jobs: - build-jon: - steps: - - name: Install .NET 9 - uses: actions/setup-dotnet@v4 - with: - dotnet-version: $DOTNET_VERSION - - name: Restore - run: dotnet restore - - name: Build - run: dotnet build $SEARCH_PATTERN --no-restore --configuration $CONFIGURATION --platform $PLATFORM - env: - SEARCH_PATTERN: ${{ inputs.search-pattern }} - DOTNET_VERSION: ${{ inputs.dotnet-version }} - CONFIGURATION: ${{ inputs.configuration }} - PLATFORM: ${{ inputs.platform }} \ No newline at end of file diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d385b17a..14286b00 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -16,10 +16,8 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: 9.x - - name: Restore - run: dotnet restore ./src/**/*.csproj - name: Build - run: dotnet build ./src/**/*.csproj --no-restore --configuration Release + run: dotnet build ./src/**/*.csproj --configuration Release - name: Upload uses: actions/upload-artifact@v4 with: @@ -64,7 +62,7 @@ jobs: - name: Display structure of downloaded files run: ls -R - name: Pack - run: dotnet pack ./src/**/*.csproj --no-build --configuration Release + run: dotnet pack ./src/**/*.csproj --configuration Release - name: Upload uses: actions/upload-artifact@v4 with: From 7d33da8bf3ae5bf7cef48d739199503997632187 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 21:42:14 +0100 Subject: [PATCH 181/352] fzdsdf --- .github/workflows/dotnet.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 14286b00..964789af 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -23,8 +23,8 @@ jobs: with: name: build path: | - /**/bin/* - /**/obj/* + ./src/**/bin/* + ./src/**/obj/* test: name: Test with MsTest @@ -68,4 +68,4 @@ jobs: with: name: package path: | - **/*.nupkg + ./src/**/*.nupkg From e991fb07740a8a6ddda0c2dd31199e509bee0fda Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 21:50:52 +0100 Subject: [PATCH 182/352] xzfa --- .github/workflows/dotnet.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 964789af..c2478514 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -63,6 +63,8 @@ jobs: run: ls -R - name: Pack run: dotnet pack ./src/**/*.csproj --configuration Release + - name: Display structure of after pack + run: ls -R - name: Upload uses: actions/upload-artifact@v4 with: From e15afd04ccd7512640ceb9c29472927264992307 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 21:55:20 +0100 Subject: [PATCH 183/352] `lsjdlsi --- .github/workflows/dotnet.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c2478514..979ffe70 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -17,7 +17,7 @@ jobs: with: dotnet-version: 9.x - name: Build - run: dotnet build ./src/**/*.csproj --configuration Release + run: dotnet build ./src/**/*.csproj --configuration Release --Platforem AnyCPU - name: Upload uses: actions/upload-artifact@v4 with: @@ -37,7 +37,7 @@ jobs: with: dotnet-version: 9.x - name: Test - run: dotnet test ./tests/**/*Tests.csproj --configuration Release --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results + run: dotnet test ./tests/**/*Tests.csproj --configuration Release --Platforem AnyCPU --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results - name: Upload uses: actions/upload-artifact@v4 with: @@ -62,7 +62,7 @@ jobs: - name: Display structure of downloaded files run: ls -R - name: Pack - run: dotnet pack ./src/**/*.csproj --configuration Release + run: dotnet pack ./src/**/*.csproj --no-build --no-restore --configuration Release --Platforem AnyCPU - name: Display structure of after pack run: ls -R - name: Upload From a5cf32569538dcd2b7b7853ff1a9b7b36fbbf4b8 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 22:21:59 +0100 Subject: [PATCH 184/352] fixed typo --- .github/workflows/dotnet.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 979ffe70..167c1dce 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -17,7 +17,7 @@ jobs: with: dotnet-version: 9.x - name: Build - run: dotnet build ./src/**/*.csproj --configuration Release --Platforem AnyCPU + run: dotnet build ./src/**/*.csproj --configuration Release --Platform AnyCPU - name: Upload uses: actions/upload-artifact@v4 with: @@ -37,7 +37,7 @@ jobs: with: dotnet-version: 9.x - name: Test - run: dotnet test ./tests/**/*Tests.csproj --configuration Release --Platforem AnyCPU --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results + run: dotnet test ./tests/**/*Tests.csproj --configuration Release --Platform AnyCPU --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results - name: Upload uses: actions/upload-artifact@v4 with: @@ -62,7 +62,7 @@ jobs: - name: Display structure of downloaded files run: ls -R - name: Pack - run: dotnet pack ./src/**/*.csproj --no-build --no-restore --configuration Release --Platforem AnyCPU + run: dotnet pack ./src/**/*.csproj --no-build --no-restore --configuration Release --Platform AnyCPU - name: Display structure of after pack run: ls -R - name: Upload From 517bbfe4546c203ee47125969607841e18e1cd0a Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 22:47:18 +0100 Subject: [PATCH 185/352] fixed platform arg --- .github/workflows/dotnet.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 167c1dce..0b79cb3f 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -17,7 +17,7 @@ jobs: with: dotnet-version: 9.x - name: Build - run: dotnet build ./src/**/*.csproj --configuration Release --Platform AnyCPU + run: dotnet build ./src/**/*.csproj --configuration Release /p:Platform AnyCPU - name: Upload uses: actions/upload-artifact@v4 with: @@ -37,7 +37,7 @@ jobs: with: dotnet-version: 9.x - name: Test - run: dotnet test ./tests/**/*Tests.csproj --configuration Release --Platform AnyCPU --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results + run: dotnet test ./tests/**/*Tests.csproj --configuration Release /p:Platform AnyCPU --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results - name: Upload uses: actions/upload-artifact@v4 with: @@ -62,7 +62,7 @@ jobs: - name: Display structure of downloaded files run: ls -R - name: Pack - run: dotnet pack ./src/**/*.csproj --no-build --no-restore --configuration Release --Platform AnyCPU + run: dotnet pack ./src/**/*.csproj --no-build --no-restore --configuration Release /p:Platform AnyCPU - name: Display structure of after pack run: ls -R - name: Upload From 040322145400236a282c93f01819515515a8afea Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 22:54:36 +0100 Subject: [PATCH 186/352] fix platform arg --- .github/workflows/dotnet.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 0b79cb3f..9e4a41b5 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -17,7 +17,7 @@ jobs: with: dotnet-version: 9.x - name: Build - run: dotnet build ./src/**/*.csproj --configuration Release /p:Platform AnyCPU + run: dotnet build ./src/**/*.csproj --configuration Release /p:Platform=AnyCPU - name: Upload uses: actions/upload-artifact@v4 with: @@ -37,7 +37,7 @@ jobs: with: dotnet-version: 9.x - name: Test - run: dotnet test ./tests/**/*Tests.csproj --configuration Release /p:Platform AnyCPU --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results + run: dotnet test ./tests/**/*Tests.csproj --configuration Release /p:Platform=AnyCPU --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results - name: Upload uses: actions/upload-artifact@v4 with: @@ -62,7 +62,7 @@ jobs: - name: Display structure of downloaded files run: ls -R - name: Pack - run: dotnet pack ./src/**/*.csproj --no-build --no-restore --configuration Release /p:Platform AnyCPU + run: dotnet pack ./src/**/*.csproj --no-build --no-restore --configuration Release /p:Platform=AnyCPU - name: Display structure of after pack run: ls -R - name: Upload From 50c03616e55a794e6d65e454798e0b845c370374 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 22:59:02 +0100 Subject: [PATCH 187/352] fixed path --- .github/workflows/dotnet.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 9e4a41b5..43a6c03e 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -23,8 +23,8 @@ jobs: with: name: build path: | - ./src/**/bin/* - ./src/**/obj/* + **/bin/* + **/obj/* test: name: Test with MsTest @@ -70,4 +70,4 @@ jobs: with: name: package path: | - ./src/**/*.nupkg + **/*.nupkg From a83b9dfdf847641c981816605e6d2cb27f46e0cf Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sat, 1 Feb 2025 23:02:09 +0100 Subject: [PATCH 188/352] removed ls -R --- .github/workflows/dotnet.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 43a6c03e..c4e15603 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -59,12 +59,8 @@ jobs: uses: actions/download-artifact@v4 with: name: build - - name: Display structure of downloaded files - run: ls -R - name: Pack run: dotnet pack ./src/**/*.csproj --no-build --no-restore --configuration Release /p:Platform=AnyCPU - - name: Display structure of after pack - run: ls -R - name: Upload uses: actions/upload-artifact@v4 with: From 3076bd5b856bed738269fbb401b2757bc6c8bead Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 12:51:49 +0100 Subject: [PATCH 189/352] testing repository variables --- .github/workflows/dotnet.yml | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c4e15603..f297ebee 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -2,20 +2,23 @@ name: .NET on: push: - branches: [ "main" ] + branches: [ $default-branch ] pull_request: - branches: [ "main" ] + branches: [ $default-branch ] + +env: + dotnet_version: ${{ vars.DOTNET_VERSION }} jobs: build: - name: Build with .NET 9 + name: Build with .NET $dotnet_version runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install .NET 9 + - name: Install .NET $dotnet_version uses: actions/setup-dotnet@v4 with: - dotnet-version: 9.x + dotnet-version: $dotnet_version - name: Build run: dotnet build ./src/**/*.csproj --configuration Release /p:Platform=AnyCPU - name: Upload @@ -27,15 +30,15 @@ jobs: **/obj/* test: - name: Test with MsTest + name: Test with .NET $dotnet_version needs: [build] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Setup .NET 9 + - name: Setup .NET $dotnet_version uses: actions/setup-dotnet@v4 with: - dotnet-version: 9.x + dotnet-version: $dotnet_version - name: Test run: dotnet test ./tests/**/*Tests.csproj --configuration Release /p:Platform=AnyCPU --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results - name: Upload @@ -46,15 +49,15 @@ jobs: **/test-results/* pack: - name: Pack with .NET 9 + name: Pack with .NET $dotnet_version needs: [test] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install .NET 9 + - name: Install .NET $dotnet_version uses: actions/setup-dotnet@v4 with: - dotnet-version: 9.x + dotnet-version: $dotnet_version - name: Download uses: actions/download-artifact@v4 with: From f067e2822d89b7886ffa4ac3d72bc5ea29948528 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 12:54:46 +0100 Subject: [PATCH 190/352] skzjhds --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index f297ebee..0a3a78c5 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -4,7 +4,7 @@ on: push: branches: [ $default-branch ] pull_request: - branches: [ $default-branch ] + branches: [ 'main' ] env: dotnet_version: ${{ vars.DOTNET_VERSION }} From acef797a40bfd41c4494727d9a8e783a62239a69 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 13:00:33 +0100 Subject: [PATCH 191/352] updated --- .github/workflows/dotnet.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 0a3a78c5..219c09ec 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -4,14 +4,14 @@ on: push: branches: [ $default-branch ] pull_request: - branches: [ 'main' ] + branches: [ $default-branch ] env: dotnet_version: ${{ vars.DOTNET_VERSION }} jobs: build: - name: Build with .NET $dotnet_version + name: Build with .NET ${{ env.$dotnet_version }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -30,7 +30,7 @@ jobs: **/obj/* test: - name: Test with .NET $dotnet_version + name: Test with .NET ${{ env.$dotnet_version }} needs: [build] runs-on: ubuntu-latest steps: @@ -49,7 +49,7 @@ jobs: **/test-results/* pack: - name: Pack with .NET $dotnet_version + name: Pack with .NET ${{ env.$dotnet_version }} needs: [test] runs-on: ubuntu-latest steps: From 705301919e6ac9fc47bfbf12c33472904f7d50bb Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 13:02:04 +0100 Subject: [PATCH 192/352] fix --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 219c09ec..1e79f10a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -4,7 +4,7 @@ on: push: branches: [ $default-branch ] pull_request: - branches: [ $default-branch ] + branches: [ 'main' ] env: dotnet_version: ${{ vars.DOTNET_VERSION }} From 6320d9d1323a97b35b06978f154fd985d6505ed0 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 13:03:33 +0100 Subject: [PATCH 193/352] added concurrency --- .github/workflows/dotnet.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 1e79f10a..11843c62 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -6,6 +6,8 @@ on: pull_request: branches: [ 'main' ] +concurrency: ${{ github.ref }} + env: dotnet_version: ${{ vars.DOTNET_VERSION }} From b687e150de2e87d248a884361a530f764a64662e Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 13:04:37 +0100 Subject: [PATCH 194/352] whhhaaaat --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 11843c62..80402834 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -6,11 +6,11 @@ on: pull_request: branches: [ 'main' ] -concurrency: ${{ github.ref }} - env: dotnet_version: ${{ vars.DOTNET_VERSION }} +concurrency: ${{ github.ref }} + jobs: build: name: Build with .NET ${{ env.$dotnet_version }} From 3507d0f8cbcb1a4f1ffb40687ffaa03c87254d8d Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 13:07:29 +0100 Subject: [PATCH 195/352] fix --- .github/workflows/dotnet.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 80402834..63421bfd 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -7,20 +7,20 @@ on: branches: [ 'main' ] env: - dotnet_version: ${{ vars.DOTNET_VERSION }} + DOTNET_VERSION: ${{ vars.DOTNET_VERSION }} concurrency: ${{ github.ref }} jobs: build: - name: Build with .NET ${{ env.$dotnet_version }} + name: Build with .NET ${{ DOTNET_VERSION }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install .NET $dotnet_version + - name: Install .NET ${{ DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: - dotnet-version: $dotnet_version + dotnet-version: $DOTNET_VERSION - name: Build run: dotnet build ./src/**/*.csproj --configuration Release /p:Platform=AnyCPU - name: Upload @@ -32,15 +32,15 @@ jobs: **/obj/* test: - name: Test with .NET ${{ env.$dotnet_version }} + name: Test with .NET ${{ DOTNET_VERSION }} needs: [build] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Setup .NET $dotnet_version + - name: Setup .NET ${{ DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: - dotnet-version: $dotnet_version + dotnet-version: $DOTNET_VERSION - name: Test run: dotnet test ./tests/**/*Tests.csproj --configuration Release /p:Platform=AnyCPU --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results - name: Upload @@ -51,15 +51,15 @@ jobs: **/test-results/* pack: - name: Pack with .NET ${{ env.$dotnet_version }} + name: Pack with .NET ${{ DOTNET_VERSION }} needs: [test] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install .NET $dotnet_version + - name: Install .NET ${{ DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: - dotnet-version: $dotnet_version + dotnet-version: $DOTNET_VERSION - name: Download uses: actions/download-artifact@v4 with: From 4f00a8f50220e15bd0316333e29346a257cc88c2 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 13:10:05 +0100 Subject: [PATCH 196/352] fux --- .github/workflows/dotnet.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 63421bfd..58647802 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,11 +13,11 @@ concurrency: ${{ github.ref }} jobs: build: - name: Build with .NET ${{ DOTNET_VERSION }} + name: Build with .NET $DOTNET_VERSION runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install .NET ${{ DOTNET_VERSION }} + - name: Install .NET $DOTNET_VERSION uses: actions/setup-dotnet@v4 with: dotnet-version: $DOTNET_VERSION @@ -32,12 +32,12 @@ jobs: **/obj/* test: - name: Test with .NET ${{ DOTNET_VERSION }} + name: Test with .NET $DOTNET_VERSION needs: [build] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Setup .NET ${{ DOTNET_VERSION }} + - name: Setup .NET $DOTNET_VERSION uses: actions/setup-dotnet@v4 with: dotnet-version: $DOTNET_VERSION @@ -51,12 +51,12 @@ jobs: **/test-results/* pack: - name: Pack with .NET ${{ DOTNET_VERSION }} + name: Pack with .NET $DOTNET_VERSION needs: [test] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install .NET ${{ DOTNET_VERSION }} + - name: Install .NET $DOTNET_VERSION uses: actions/setup-dotnet@v4 with: dotnet-version: $DOTNET_VERSION From 2c6399b3d0ba0598c137188619ee6c22205ee68c Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 13:11:48 +0100 Subject: [PATCH 197/352] fix --- .github/workflows/dotnet.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 58647802..d4f7494e 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,11 +13,11 @@ concurrency: ${{ github.ref }} jobs: build: - name: Build with .NET $DOTNET_VERSION + name: Build with .NET ${{ env.DOTNET_VERSION }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install .NET $DOTNET_VERSION + - name: Install .NET ${{ env.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: dotnet-version: $DOTNET_VERSION @@ -32,7 +32,7 @@ jobs: **/obj/* test: - name: Test with .NET $DOTNET_VERSION + name: Test with .NET ${{ env.DOTNET_VERSION }} needs: [build] runs-on: ubuntu-latest steps: @@ -40,7 +40,7 @@ jobs: - name: Setup .NET $DOTNET_VERSION uses: actions/setup-dotnet@v4 with: - dotnet-version: $DOTNET_VERSION + dotnet-version: ${{ env.DOTNET_VERSION }} - name: Test run: dotnet test ./tests/**/*Tests.csproj --configuration Release /p:Platform=AnyCPU --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results - name: Upload @@ -51,12 +51,12 @@ jobs: **/test-results/* pack: - name: Pack with .NET $DOTNET_VERSION + name: Pack with .NET ${{ env.DOTNET_VERSION }} needs: [test] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install .NET $DOTNET_VERSION + - name: Install .NET ${{ env.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: dotnet-version: $DOTNET_VERSION From d75b6a9f41f0a33fb83408178f606b8cdad03f99 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 13:14:33 +0100 Subject: [PATCH 198/352] fix --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d4f7494e..f7d27684 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -20,7 +20,7 @@ jobs: - name: Install .NET ${{ env.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: - dotnet-version: $DOTNET_VERSION + dotnet-version: ${{ env.DOTNET_VERSION }} - name: Build run: dotnet build ./src/**/*.csproj --configuration Release /p:Platform=AnyCPU - name: Upload @@ -59,7 +59,7 @@ jobs: - name: Install .NET ${{ env.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: - dotnet-version: $DOTNET_VERSION + dotnet-version: ${{ env.DOTNET_VERSION }} - name: Download uses: actions/download-artifact@v4 with: From 597ba041d5f97fe2237bcfc645bd1398c4128740 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 13:16:38 +0100 Subject: [PATCH 199/352] test --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index f7d27684..906dcb77 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,7 +13,7 @@ concurrency: ${{ github.ref }} jobs: build: - name: Build with .NET ${{ env.DOTNET_VERSION }} + name: Build with .NET ${{ DOTNET_VERSION }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 From 6c62c0be33b09db0fd386f6083c6a91bef22bc49 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 13:17:56 +0100 Subject: [PATCH 200/352] fix --- .github/workflows/dotnet.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 906dcb77..c41bcc9d 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -7,20 +7,20 @@ on: branches: [ 'main' ] env: - DOTNET_VERSION: ${{ vars.DOTNET_VERSION }} + dotnet_version: ${{ vars.DOTNET_VERSION }} concurrency: ${{ github.ref }} jobs: build: - name: Build with .NET ${{ DOTNET_VERSION }} + name: Build with .NET ${{ env.dotnet_version }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install .NET ${{ env.DOTNET_VERSION }} + - name: Install .NET ${{ env.dotnet_version }} uses: actions/setup-dotnet@v4 with: - dotnet-version: ${{ env.DOTNET_VERSION }} + dotnet-version: ${{ env.dotnet_version }} - name: Build run: dotnet build ./src/**/*.csproj --configuration Release /p:Platform=AnyCPU - name: Upload From 5c433eb5daddf577c43af0f47fe9b17c671029a6 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 13:34:13 +0100 Subject: [PATCH 201/352] fix --- .github/workflows/dotnet.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c41bcc9d..61bdcce6 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,14 +13,14 @@ concurrency: ${{ github.ref }} jobs: build: - name: Build with .NET ${{ env.dotnet_version }} + name: Build with .NET ${{ vars.DOTNET_VERSION }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install .NET ${{ env.dotnet_version }} + - name: Install .NET ${{ vars.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: - dotnet-version: ${{ env.dotnet_version }} + dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Build run: dotnet build ./src/**/*.csproj --configuration Release /p:Platform=AnyCPU - name: Upload @@ -32,15 +32,15 @@ jobs: **/obj/* test: - name: Test with .NET ${{ env.DOTNET_VERSION }} + name: Test with .NET ${{ vars.DOTNET_VERSION }} needs: [build] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Setup .NET $DOTNET_VERSION + - name: Setup .NET ${{ vars.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: - dotnet-version: ${{ env.DOTNET_VERSION }} + dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Test run: dotnet test ./tests/**/*Tests.csproj --configuration Release /p:Platform=AnyCPU --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results - name: Upload @@ -51,15 +51,15 @@ jobs: **/test-results/* pack: - name: Pack with .NET ${{ env.DOTNET_VERSION }} + name: Pack with .NET ${{ vars.DOTNET_VERSION }} needs: [test] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install .NET ${{ env.DOTNET_VERSION }} + - name: Install .NET ${{ vars.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: - dotnet-version: ${{ env.DOTNET_VERSION }} + dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Download uses: actions/download-artifact@v4 with: From 90377384228ba6445aa13f5ec70fb1bc4f03b791 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 13:40:03 +0100 Subject: [PATCH 202/352] slfajwdl --- .github/workflows/dotnet.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 61bdcce6..fab1801e 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -22,7 +22,7 @@ jobs: with: dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Build - run: dotnet build ./src/**/*.csproj --configuration Release /p:Platform=AnyCPU + run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} - name: Upload uses: actions/upload-artifact@v4 with: @@ -42,7 +42,7 @@ jobs: with: dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Test - run: dotnet test ./tests/**/*Tests.csproj --configuration Release /p:Platform=AnyCPU --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results + run: dotnet test ./tests/**/*Tests.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results - name: Upload uses: actions/upload-artifact@v4 with: @@ -65,7 +65,7 @@ jobs: with: name: build - name: Pack - run: dotnet pack ./src/**/*.csproj --no-build --no-restore --configuration Release /p:Platform=AnyCPU + run: dotnet pack ./src/**/*.csproj --no-build --no-restore --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} - name: Upload uses: actions/upload-artifact@v4 with: From cde619a91b308d73dc5911dba6b530322273e0fa Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 13:46:31 +0100 Subject: [PATCH 203/352] dsafsd --- .github/workflows/dotnet.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index fab1801e..a1959715 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -21,9 +21,9 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ vars.DOTNET_VERSION }} - - name: Build + - name: Build with .NET ${{ vars.DOTNET_VERSION }} run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} - - name: Upload + - name: Upload Build uses: actions/upload-artifact@v4 with: name: build @@ -41,9 +41,9 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ vars.DOTNET_VERSION }} - - name: Test + - name: Test with .NET ${{ vars.DOTNET_VERSION }} run: dotnet test ./tests/**/*Tests.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results - - name: Upload + - name: Upload Test Results uses: actions/upload-artifact@v4 with: name: test-results @@ -60,13 +60,13 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ vars.DOTNET_VERSION }} - - name: Download + - name: Download Build uses: actions/download-artifact@v4 with: name: build - - name: Pack + - name: Pack with .NET ${{ vars.DOTNET_VERSION }} run: dotnet pack ./src/**/*.csproj --no-build --no-restore --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} - - name: Upload + - name: Upload Package uses: actions/upload-artifact@v4 with: name: package From 42c802fbdcee779f15fcc718c187bca0278834da Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 20:15:05 +0100 Subject: [PATCH 204/352] gitversion test --- .github/workflows/dotnet.yml | 31 +++++++-- .gitversion/version.yml | 126 +++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 .gitversion/version.yml diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index a1959715..be2b5b7c 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -2,16 +2,37 @@ name: .NET on: push: - branches: [ $default-branch ] + branches: + - '**' pull_request: - branches: [ 'main' ] - -env: - dotnet_version: ${{ vars.DOTNET_VERSION }} + branches: + - '**' concurrency: ${{ github.ref }} jobs: + version: + name: Version with GitVersion ${{ vars.GIT_VERSION }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Install GitVersion ${{ vars.GIT_VERSION }} + uses: gittools/actions/gitversion/setup@v3.1.11 + with: + versionSpec: ${{ vars.GIT_VERSION }} + preferLatestVersion: true + - name: Update Version with GitVersion ${{ vars.GIT_VERSION }} + uses: gittools/actions/gitversion/execute@v3.1.11 + with: + useConfigFile: true + configFilePath: ./.gitversion/version.yml + updateAssemblyInfo: true + - name: Write Version + run: echo ${{ env.GitVersion_FullSemVer }} + + build: name: Build with .NET ${{ vars.DOTNET_VERSION }} runs-on: ubuntu-latest diff --git a/.gitversion/version.yml b/.gitversion/version.yml new file mode 100644 index 00000000..efcb1a95 --- /dev/null +++ b/.gitversion/version.yml @@ -0,0 +1,126 @@ +# Global settings +assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 0}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 0}' +tag-prefix: '[vV]?' +version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* +major-version-bump-message: '' +minor-version-bump-message: '' +patch-version-bump-message: '' +no-bump-message: '' +tag-pre-release-weight: 60000 +commit-date-format: yyyy-MM-dd +merge-message-formats: {} +update-build-number: false +semantic-version-format: Strict +strategies: +- VersionInBranchName +- TrackReleaseBranches +mode: ContinuousDelivery +label: '' +increment: Patch +prevent-increment: + of-merged-branch: true + when-branch-merged: true + when-current-commit-tagged: true +track-merge: + target: false + message: false +commit-message-incrementing: Disabled +regex: '' +source-branches: [] +is-source-branch-for: [] +tracks-release-branches: false +is-release-branch: false +is-main-branch: false +ignore: + sha: [] +# Branch settings +branches: + # Release branch - branch tracks history for specific version + release: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+)$ + increment: Inherit + is-release-branch: true + # Preview branch - branch accumulates changes for specific version before it is first released + preview: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+\/preview)$ + increment: Inherit + source-branches: + - release + # Hotfix branch - branch hotfixes a critical bug for specific version after it was first released + hotfix: + mode: ContinuousDeployment + label: '{BranchName}' + increment: Inherit + regex: ^hotfix?[/-](?.+) + tracks-release-branches: true + source-branches: + - release + # Support branch - branch accumulates changes for specific version after it was first released + support: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+\/support)$ + increment: Inherit + source-branches: + - release +# Bugfixes branch - branch hotfixes bugs for specific version after it was first released + bugfix: + mode: ContinuousDeployment + label: '{BranchName}' + increment: Inherit + regex: ^bugfix?[/-](?.+) + tracks-release-branches: true + source-branches: + - support + # Feature branch - branch accumulates changes for specific version after it was first released + feature: + mode: ContinuousDeployment + label: '{BranchName}' + increment: Inherit + regex: ^feature?[/-](?.+)$ + tracks-release-branches: true + source-branches: + - preview + # PR branch - branch merges a source branch to a target branch + pull-request: + mode: ContinuousDeployment + label: pull-request + increment: Inherit + label-number-pattern: '[/-](?\d+)' + regex: ^(pull|pull\-requests|pr)[/-] + source-branches: + - main + - release + - preview + - hotfix + - support + - bugfix + - feature + # Main branch - branch tracks historical changes between releases + main: + mode: ManualDeployment + increment: Inherit + regex: ^main$ + tracks-release-branches: true + prevent-increment: + of-merged-branch: false + is-main-branch: true + source-branches: + - release + # Any other branch + unknown: + mode: ManualDeployment + label: '{BranchName}' + increment: Inherit + regex: (?.+) + source-branches: + - main + - release + - preview + - hotfix + - support + - bugfix + - feature + - pull-request From cef9550e0e80c402ee8deda86804c8c454a52716 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 20:21:28 +0100 Subject: [PATCH 205/352] test --- .github/workflows/dotnet.yml | 59 ++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index be2b5b7c..c359e878 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -24,17 +24,72 @@ jobs: versionSpec: ${{ vars.GIT_VERSION }} preferLatestVersion: true - name: Update Version with GitVersion ${{ vars.GIT_VERSION }} + id: version_step uses: gittools/actions/gitversion/execute@v3.1.11 with: useConfigFile: true configFilePath: ./.gitversion/version.yml updateAssemblyInfo: true - - name: Write Version - run: echo ${{ env.GitVersion_FullSemVer }} + - run: | + echo "FullSemVer (env.fullSemVer) : ${{ env.fullSemVer }}" + name: Display GitVersion variables (without prefix) + + - run: | + echo "FullSemVer (env.GitVersion_FullSemVer) : ${{ env.GitVersion_FullSemVer }}" + name: Display GitVersion variables (with prefix) + + - run: | + echo "FullSemVer (steps.version_step.outputs.fullSemVer) : ${{ steps.version_step.outputs.fullSemVer }}" + name: Display GitVersion outputs (step output without prefix) + + - run: | + echo "FullSemVer (steps.version_step.outputs.GitVersion_FullSemVer) : ${{ steps.version_step.outputs.GitVersion_FullSemVer }}" + name: Display GitVersion outputs (step output with prefix) + + - run: | + echo "FullSemVer (env.myvar_fullSemVer) : ${{ env.myvar_fullSemVer }}" + name: Display mapped local env (outputs without prefix) + env: + myvar_fullSemVer: ${{ steps.version_step.outputs.fullSemVer }} + + - run: | + echo "FullSemVer (env.myvar_GitVersion_FullSemVer) : ${{ env.myvar_GitVersion_FullSemVer }}" + name: Display mapped local env (outputs with prefix) + env: + myvar_GitVersion_FullSemVer: ${{ steps.version_step.outputs.GitVersion_FullSemVer }} + + - run: | + echo "FullSemVer (env.myvar_fullSemVer) : $env:myvar_fullSemVer" + name: Display mapped local env (pwsh - outputs without prefix) + shell: pwsh + env: + myvar_fullSemVer: ${{ steps.version_step.outputs.fullSemVer }} + + - run: | + echo "FullSemVer (env.myvar_GitVersion_FullSemVer) : $env:myvar_GitVersion_FullSemVer" + name: Display mapped local env (pwsh - outputs with prefix) + shell: pwsh + env: + myvar_GitVersion_FullSemVer: ${{ steps.version_step.outputs.GitVersion_FullSemVer }} + + - run: | + echo "FullSemVer (myvar_fullSemVer) : $myvar_fullSemVer" + name: Display mapped local env (bash - outputs without prefix) + shell: bash + env: + myvar_fullSemVer: ${{ steps.version_step.outputs.fullSemVer }} + + - run: | + echo "FullSemVer (myvar_GitVersion_FullSemVer) : $myvar_GitVersion_FullSemVer" + name: Display mapped local env (bash - outputs with prefix) + shell: bash + env: + myvar_GitVersion_FullSemVer: ${{ steps.version_step.outputs.GitVersion_FullSemVer }} build: name: Build with .NET ${{ vars.DOTNET_VERSION }} + needs: [version] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 From f8aa13608e53fbfa211066ac0ced8677e0540549 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 20:30:26 +0100 Subject: [PATCH 206/352] test --- .gitversion/version.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index efcb1a95..78e5ea3a 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -39,13 +39,13 @@ branches: # Release branch - branch tracks history for specific version release: mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+)$ + regex: ^(release[\/][\d]+\.[\d]+) increment: Inherit is-release-branch: true # Preview branch - branch accumulates changes for specific version before it is first released preview: mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+\/preview)$ + regex: ^(release[\/][\d]+\.[\d]+\/preview) increment: Inherit source-branches: - release @@ -61,7 +61,7 @@ branches: # Support branch - branch accumulates changes for specific version after it was first released support: mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+\/support)$ + regex: ^(release[\/][\d]+\.[\d]+\/support) increment: Inherit source-branches: - release @@ -79,7 +79,7 @@ branches: mode: ContinuousDeployment label: '{BranchName}' increment: Inherit - regex: ^feature?[/-](?.+)$ + regex: ^feature?[/-](?.+) tracks-release-branches: true source-branches: - preview From 2036e9d2601d48a428d632e6560f9ddfbe9e17fc Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 20:31:35 +0100 Subject: [PATCH 207/352] test --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c359e878..aebd9029 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -29,7 +29,7 @@ jobs: with: useConfigFile: true configFilePath: ./.gitversion/version.yml - updateAssemblyInfo: true + updateAssemblyInfo: false - run: | echo "FullSemVer (env.fullSemVer) : ${{ env.fullSemVer }}" name: Display GitVersion variables (without prefix) From 03832bafd0084b6aab2fb3e67d702c17efe23cbe Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 20:38:06 +0100 Subject: [PATCH 208/352] test --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index aebd9029..32e39aeb 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -27,7 +27,7 @@ jobs: id: version_step uses: gittools/actions/gitversion/execute@v3.1.11 with: - useConfigFile: true + useConfigFile: false configFilePath: ./.gitversion/version.yml updateAssemblyInfo: false - run: | From 3df61af76eccd2f63dabae8c3a4c0d64c7e57f45 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 20:40:28 +0100 Subject: [PATCH 209/352] asd --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 32e39aeb..aebd9029 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -27,7 +27,7 @@ jobs: id: version_step uses: gittools/actions/gitversion/execute@v3.1.11 with: - useConfigFile: false + useConfigFile: true configFilePath: ./.gitversion/version.yml updateAssemblyInfo: false - run: | From 7c76dce3bbc2125df6e4fea244da9d8eb9eb44d4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 20:45:00 +0100 Subject: [PATCH 210/352] kshfda --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 78e5ea3a..0f68f899 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,6 +1,6 @@ # Global settings -assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 0}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 0}' +assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 42}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 42}' tag-prefix: '[vV]?' version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* major-version-bump-message: '' From 98aee68e33dd591eb6a9002ef7a417d7b18704e9 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 20:46:30 +0100 Subject: [PATCH 211/352] test --- .gitversion/version (2).yml | 126 ++++++++++++++++++++++ .gitversion/version.yml | 209 ++++++++++++++++-------------------- 2 files changed, 220 insertions(+), 115 deletions(-) create mode 100644 .gitversion/version (2).yml diff --git a/.gitversion/version (2).yml b/.gitversion/version (2).yml new file mode 100644 index 00000000..0f68f899 --- /dev/null +++ b/.gitversion/version (2).yml @@ -0,0 +1,126 @@ +# Global settings +assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 42}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 42}' +tag-prefix: '[vV]?' +version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* +major-version-bump-message: '' +minor-version-bump-message: '' +patch-version-bump-message: '' +no-bump-message: '' +tag-pre-release-weight: 60000 +commit-date-format: yyyy-MM-dd +merge-message-formats: {} +update-build-number: false +semantic-version-format: Strict +strategies: +- VersionInBranchName +- TrackReleaseBranches +mode: ContinuousDelivery +label: '' +increment: Patch +prevent-increment: + of-merged-branch: true + when-branch-merged: true + when-current-commit-tagged: true +track-merge: + target: false + message: false +commit-message-incrementing: Disabled +regex: '' +source-branches: [] +is-source-branch-for: [] +tracks-release-branches: false +is-release-branch: false +is-main-branch: false +ignore: + sha: [] +# Branch settings +branches: + # Release branch - branch tracks history for specific version + release: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+) + increment: Inherit + is-release-branch: true + # Preview branch - branch accumulates changes for specific version before it is first released + preview: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+\/preview) + increment: Inherit + source-branches: + - release + # Hotfix branch - branch hotfixes a critical bug for specific version after it was first released + hotfix: + mode: ContinuousDeployment + label: '{BranchName}' + increment: Inherit + regex: ^hotfix?[/-](?.+) + tracks-release-branches: true + source-branches: + - release + # Support branch - branch accumulates changes for specific version after it was first released + support: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+\/support) + increment: Inherit + source-branches: + - release +# Bugfixes branch - branch hotfixes bugs for specific version after it was first released + bugfix: + mode: ContinuousDeployment + label: '{BranchName}' + increment: Inherit + regex: ^bugfix?[/-](?.+) + tracks-release-branches: true + source-branches: + - support + # Feature branch - branch accumulates changes for specific version after it was first released + feature: + mode: ContinuousDeployment + label: '{BranchName}' + increment: Inherit + regex: ^feature?[/-](?.+) + tracks-release-branches: true + source-branches: + - preview + # PR branch - branch merges a source branch to a target branch + pull-request: + mode: ContinuousDeployment + label: pull-request + increment: Inherit + label-number-pattern: '[/-](?\d+)' + regex: ^(pull|pull\-requests|pr)[/-] + source-branches: + - main + - release + - preview + - hotfix + - support + - bugfix + - feature + # Main branch - branch tracks historical changes between releases + main: + mode: ManualDeployment + increment: Inherit + regex: ^main$ + tracks-release-branches: true + prevent-increment: + of-merged-branch: false + is-main-branch: true + source-branches: + - release + # Any other branch + unknown: + mode: ManualDeployment + label: '{BranchName}' + increment: Inherit + regex: (?.+) + source-branches: + - main + - release + - preview + - hotfix + - support + - bugfix + - feature + - pull-request diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 0f68f899..eae2db88 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,126 +1,105 @@ -# Global settings -assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 42}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 42}' -tag-prefix: '[vV]?' -version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* -major-version-bump-message: '' -minor-version-bump-message: '' -patch-version-bump-message: '' -no-bump-message: '' -tag-pre-release-weight: 60000 -commit-date-format: yyyy-MM-dd -merge-message-formats: {} -update-build-number: false -semantic-version-format: Strict -strategies: -- VersionInBranchName -- TrackReleaseBranches -mode: ContinuousDelivery -label: '' -increment: Patch -prevent-increment: - of-merged-branch: true - when-branch-merged: true - when-current-commit-tagged: true -track-merge: - target: false - message: false -commit-message-incrementing: Disabled -regex: '' -source-branches: [] -is-source-branch-for: [] -tracks-release-branches: false -is-release-branch: false -is-main-branch: false +next-version: 0.2.0.0 # +assembly-versioning-scheme: MajorMinorPatchTag +assembly-file-versioning-scheme: MajorMinorPatchTag +assembly-informational-format: "{FullSemVer}" +mode: ContinuousDeployment +increment: Inherit +continuous-delivery-fallback-tag: ci +tag-prefix: "[vV]" +major-version-bump-message: '\+semver:\s?(breaking|major)' +minor-version-bump-message: '\+semver:\s?(feature|minor)' +patch-version-bump-message: '\+semver:\s?(fix|patch)' +no-bump-message: '\+semver:\s?(none|skip)' +legacy-semver-padding: 4 +build-metadata-padding: 4 +commits-since-version-source-padding: 4 +commit-message-incrementing: Enabled +commit-date-format: "yyyy-MM-dd" ignore: sha: [] -# Branch settings branches: - # Release branch - branch tracks history for specific version - release: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+) - increment: Inherit - is-release-branch: true - # Preview branch - branch accumulates changes for specific version before it is first released - preview: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+\/preview) - increment: Inherit - source-branches: - - release - # Hotfix branch - branch hotfixes a critical bug for specific version after it was first released - hotfix: - mode: ContinuousDeployment - label: '{BranchName}' - increment: Inherit - regex: ^hotfix?[/-](?.+) - tracks-release-branches: true - source-branches: - - release - # Support branch - branch accumulates changes for specific version after it was first released - support: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+\/support) - increment: Inherit - source-branches: - - release -# Bugfixes branch - branch hotfixes bugs for specific version after it was first released - bugfix: + main: + regex: ^master$|^main$ + mode: ContinuousDelivery + tag: '' + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'develop', 'release' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: true + pre-release-weight: 55000 + develop: + regex: ^dev(elop)?(ment)?$ mode: ContinuousDeployment - label: '{BranchName}' - increment: Inherit - regex: ^bugfix?[/-](?.+) + tag: alpha + increment: Minor + prevent-increment-of-merged-branch-version: false + track-merge-target: true + source-branches: [] tracks-release-branches: true - source-branches: - - support - # Feature branch - branch accumulates changes for specific version after it was first released + is-release-branch: false + is-mainline: false + pre-release-weight: 0 + release: + regex: ^release?[/-] + mode: ContinuousDelivery + tag: beta + increment: None + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'develop', 'main', 'support', 'release' ] + tracks-release-branches: false + is-release-branch: true + is-mainline: false + pre-release-weight: 30000 feature: + regex: ^feature?[/-] mode: ContinuousDeployment - label: '{BranchName}' + tag: useBranchName increment: Inherit - regex: ^feature?[/-](?.+) - tracks-release-branches: true - source-branches: - - preview - # PR branch - branch merges a source branch to a target branch + prevent-increment-of-merged-branch-version: false + track-merge-target: false + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 pull-request: - mode: ContinuousDeployment - label: pull-request - increment: Inherit - label-number-pattern: '[/-](?\d+)' regex: ^(pull|pull\-requests|pr)[/-] - source-branches: - - main - - release - - preview - - hotfix - - support - - bugfix - - feature - # Main branch - branch tracks historical changes between releases - main: - mode: ManualDeployment - increment: Inherit - regex: ^main$ - tracks-release-branches: true - prevent-increment: - of-merged-branch: false - is-main-branch: true - source-branches: - - release - # Any other branch - unknown: - mode: ManualDeployment - label: '{BranchName}' + mode: ContinuousDelivery + tag: PullRequest increment: Inherit - regex: (?.+) - source-branches: - - main - - release - - preview - - hotfix - - support - - bugfix - - feature - - pull-request + prevent-increment-of-merged-branch-version: false + tag-number-pattern: '[/-](?\d+)[-/]' + track-merge-target: false + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 + hotfix: + regex: ^hotfix(es)?[/-] + mode: ContinuousDelivery + tag: beta + increment: Patch + prevent-increment-of-merged-branch-version: false + track-merge-target: false + source-branches: [ 'develop', 'main', 'support' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 + support: + regex: ^support[/-] + mode: ContinuousDelivery + tag: '' + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'main' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: true + pre-release-weight: 55000 \ No newline at end of file From c443329e4ea270552ee0d5adf3e665b1fef8b73a Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 20:58:32 +0100 Subject: [PATCH 212/352] dfes --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index aebd9029..ba969621 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -31,11 +31,11 @@ jobs: configFilePath: ./.gitversion/version.yml updateAssemblyInfo: false - run: | - echo "FullSemVer (env.fullSemVer) : ${{ env.fullSemVer }}" + echo "FullSemVer: ${{ env.fullSemVer }}" name: Display GitVersion variables (without prefix) - run: | - echo "FullSemVer (env.GitVersion_FullSemVer) : ${{ env.GitVersion_FullSemVer }}" + echo "FullSemVer: ${{ env.GitVersion_FullSemVer }}" name: Display GitVersion variables (with prefix) - run: | From c91038304be2b46afc430ed1d7cf1783666977e7 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 21:01:27 +0100 Subject: [PATCH 213/352] lsdhSQ --- .github/workflows/dotnet.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index ba969621..dcd09808 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -31,56 +31,56 @@ jobs: configFilePath: ./.gitversion/version.yml updateAssemblyInfo: false - run: | - echo "FullSemVer: ${{ env.fullSemVer }}" + echo FullSemVer (env.fullSemVer) : ${{ env.fullSemVer }} name: Display GitVersion variables (without prefix) - run: | - echo "FullSemVer: ${{ env.GitVersion_FullSemVer }}" + echo FullSemVer (env.GitVersion_FullSemVer) : ${{ env.GitVersion_FullSemVer }} name: Display GitVersion variables (with prefix) - run: | - echo "FullSemVer (steps.version_step.outputs.fullSemVer) : ${{ steps.version_step.outputs.fullSemVer }}" + echo FullSemVer (steps.version_step.outputs.fullSemVer) : ${{ steps.version_step.outputs.fullSemVer }} name: Display GitVersion outputs (step output without prefix) - run: | - echo "FullSemVer (steps.version_step.outputs.GitVersion_FullSemVer) : ${{ steps.version_step.outputs.GitVersion_FullSemVer }}" + echo FullSemVer (steps.version_step.outputs.GitVersion_FullSemVer) : ${{ steps.version_step.outputs.GitVersion_FullSemVer }} name: Display GitVersion outputs (step output with prefix) - run: | - echo "FullSemVer (env.myvar_fullSemVer) : ${{ env.myvar_fullSemVer }}" + echo FullSemVer (env.myvar_fullSemVer) : ${{ env.myvar_fullSemVer }} name: Display mapped local env (outputs without prefix) env: myvar_fullSemVer: ${{ steps.version_step.outputs.fullSemVer }} - run: | - echo "FullSemVer (env.myvar_GitVersion_FullSemVer) : ${{ env.myvar_GitVersion_FullSemVer }}" + echo FullSemVer (env.myvar_GitVersion_FullSemVer) : ${{ env.myvar_GitVersion_FullSemVer }} name: Display mapped local env (outputs with prefix) env: myvar_GitVersion_FullSemVer: ${{ steps.version_step.outputs.GitVersion_FullSemVer }} - run: | - echo "FullSemVer (env.myvar_fullSemVer) : $env:myvar_fullSemVer" + echo FullSemVer (env.myvar_fullSemVer) : $env:myvar_fullSemVer name: Display mapped local env (pwsh - outputs without prefix) shell: pwsh env: myvar_fullSemVer: ${{ steps.version_step.outputs.fullSemVer }} - run: | - echo "FullSemVer (env.myvar_GitVersion_FullSemVer) : $env:myvar_GitVersion_FullSemVer" + echo FullSemVer (env.myvar_GitVersion_FullSemVer) : $env:myvar_GitVersion_FullSemVer name: Display mapped local env (pwsh - outputs with prefix) shell: pwsh env: myvar_GitVersion_FullSemVer: ${{ steps.version_step.outputs.GitVersion_FullSemVer }} - run: | - echo "FullSemVer (myvar_fullSemVer) : $myvar_fullSemVer" + echo FullSemVer (myvar_fullSemVer) : $myvar_fullSemVer name: Display mapped local env (bash - outputs without prefix) shell: bash env: myvar_fullSemVer: ${{ steps.version_step.outputs.fullSemVer }} - run: | - echo "FullSemVer (myvar_GitVersion_FullSemVer) : $myvar_GitVersion_FullSemVer" + echo FullSemVer (myvar_GitVersion_FullSemVer) : $myvar_GitVersion_FullSemVer name: Display mapped local env (bash - outputs with prefix) shell: bash env: @@ -118,7 +118,7 @@ jobs: with: dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Test with .NET ${{ vars.DOTNET_VERSION }} - run: dotnet test ./tests/**/*Tests.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results + run: dotnet test ./tests/**/*Tests.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} --verbosity normal --settings unit-test.runsettings --logger trx --collect:Code Coverage --results-directory test-results - name: Upload Test Results uses: actions/upload-artifact@v4 with: From a189a36e1bec9fa1aede8609002ad3f177988e72 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 21:08:07 +0100 Subject: [PATCH 214/352] lashfda --- .github/workflows/dotnet.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index dcd09808..b447043a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -31,30 +31,30 @@ jobs: configFilePath: ./.gitversion/version.yml updateAssemblyInfo: false - run: | - echo FullSemVer (env.fullSemVer) : ${{ env.fullSemVer }} - name: Display GitVersion variables (without prefix) + echo FullSemVer: ${{ env.fullSemVer }} + name: Display GitVersion variables - run: | - echo FullSemVer (env.GitVersion_FullSemVer) : ${{ env.GitVersion_FullSemVer }} + echo FullSemVer: ${{ env.GitVersion_FullSemVer }} name: Display GitVersion variables (with prefix) - run: | - echo FullSemVer (steps.version_step.outputs.fullSemVer) : ${{ steps.version_step.outputs.fullSemVer }} - name: Display GitVersion outputs (step output without prefix) + echo FullSemVer: ${{ steps.version_step.outputs.fullSemVer }} + name: Display GitVersion outputs - run: | - echo FullSemVer (steps.version_step.outputs.GitVersion_FullSemVer) : ${{ steps.version_step.outputs.GitVersion_FullSemVer }} - name: Display GitVersion outputs (step output with prefix) + echo FullSemVer: ${{ steps.version_step.outputs.GitVersion_FullSemVer }} + name: Display GitVersion outputs - run: | - echo FullSemVer (env.myvar_fullSemVer) : ${{ env.myvar_fullSemVer }} - name: Display mapped local env (outputs without prefix) + echo FullSemVer: ${{ env.myvar_fullSemVer }} + name: Display mapped local env env: myvar_fullSemVer: ${{ steps.version_step.outputs.fullSemVer }} - run: | - echo FullSemVer (env.myvar_GitVersion_FullSemVer) : ${{ env.myvar_GitVersion_FullSemVer }} - name: Display mapped local env (outputs with prefix) + echo FullSemVer: ${{ env.myvar_GitVersion_FullSemVer }} + name: Display mapped local env env: myvar_GitVersion_FullSemVer: ${{ steps.version_step.outputs.GitVersion_FullSemVer }} From f14d97041bd868c8b22f0191073bb41adba55bb5 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 21:28:28 +0100 Subject: [PATCH 215/352] kjiu --- .github/workflows/dotnet.yml | 57 +----------------------------------- 1 file changed, 1 insertion(+), 56 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b447043a..09f9761b 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -30,62 +30,7 @@ jobs: useConfigFile: true configFilePath: ./.gitversion/version.yml updateAssemblyInfo: false - - run: | - echo FullSemVer: ${{ env.fullSemVer }} - name: Display GitVersion variables - - - run: | - echo FullSemVer: ${{ env.GitVersion_FullSemVer }} - name: Display GitVersion variables (with prefix) - - - run: | - echo FullSemVer: ${{ steps.version_step.outputs.fullSemVer }} - name: Display GitVersion outputs - - - run: | - echo FullSemVer: ${{ steps.version_step.outputs.GitVersion_FullSemVer }} - name: Display GitVersion outputs - - - run: | - echo FullSemVer: ${{ env.myvar_fullSemVer }} - name: Display mapped local env - env: - myvar_fullSemVer: ${{ steps.version_step.outputs.fullSemVer }} - - - run: | - echo FullSemVer: ${{ env.myvar_GitVersion_FullSemVer }} - name: Display mapped local env - env: - myvar_GitVersion_FullSemVer: ${{ steps.version_step.outputs.GitVersion_FullSemVer }} - - - run: | - echo FullSemVer (env.myvar_fullSemVer) : $env:myvar_fullSemVer - name: Display mapped local env (pwsh - outputs without prefix) - shell: pwsh - env: - myvar_fullSemVer: ${{ steps.version_step.outputs.fullSemVer }} - - - run: | - echo FullSemVer (env.myvar_GitVersion_FullSemVer) : $env:myvar_GitVersion_FullSemVer - name: Display mapped local env (pwsh - outputs with prefix) - shell: pwsh - env: - myvar_GitVersion_FullSemVer: ${{ steps.version_step.outputs.GitVersion_FullSemVer }} - - - run: | - echo FullSemVer (myvar_fullSemVer) : $myvar_fullSemVer - name: Display mapped local env (bash - outputs without prefix) - shell: bash - env: - myvar_fullSemVer: ${{ steps.version_step.outputs.fullSemVer }} - - - run: | - echo FullSemVer (myvar_GitVersion_FullSemVer) : $myvar_GitVersion_FullSemVer - name: Display mapped local env (bash - outputs with prefix) - shell: bash - env: - myvar_GitVersion_FullSemVer: ${{ steps.version_step.outputs.GitVersion_FullSemVer }} - + - run: 'echo FullSemVer: ${{ env.fullSemVer }}' build: name: Build with .NET ${{ vars.DOTNET_VERSION }} From c707dde5409c93a274806feb1ec294bb2f082faf Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 21:37:22 +0100 Subject: [PATCH 216/352] sadqw --- .gitversion/version (2).yml | 126 ---------------------- .gitversion/version.yml | 209 ++++++++++++++++++++---------------- 2 files changed, 115 insertions(+), 220 deletions(-) delete mode 100644 .gitversion/version (2).yml diff --git a/.gitversion/version (2).yml b/.gitversion/version (2).yml deleted file mode 100644 index 0f68f899..00000000 --- a/.gitversion/version (2).yml +++ /dev/null @@ -1,126 +0,0 @@ -# Global settings -assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 42}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 42}' -tag-prefix: '[vV]?' -version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* -major-version-bump-message: '' -minor-version-bump-message: '' -patch-version-bump-message: '' -no-bump-message: '' -tag-pre-release-weight: 60000 -commit-date-format: yyyy-MM-dd -merge-message-formats: {} -update-build-number: false -semantic-version-format: Strict -strategies: -- VersionInBranchName -- TrackReleaseBranches -mode: ContinuousDelivery -label: '' -increment: Patch -prevent-increment: - of-merged-branch: true - when-branch-merged: true - when-current-commit-tagged: true -track-merge: - target: false - message: false -commit-message-incrementing: Disabled -regex: '' -source-branches: [] -is-source-branch-for: [] -tracks-release-branches: false -is-release-branch: false -is-main-branch: false -ignore: - sha: [] -# Branch settings -branches: - # Release branch - branch tracks history for specific version - release: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+) - increment: Inherit - is-release-branch: true - # Preview branch - branch accumulates changes for specific version before it is first released - preview: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+\/preview) - increment: Inherit - source-branches: - - release - # Hotfix branch - branch hotfixes a critical bug for specific version after it was first released - hotfix: - mode: ContinuousDeployment - label: '{BranchName}' - increment: Inherit - regex: ^hotfix?[/-](?.+) - tracks-release-branches: true - source-branches: - - release - # Support branch - branch accumulates changes for specific version after it was first released - support: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+\/support) - increment: Inherit - source-branches: - - release -# Bugfixes branch - branch hotfixes bugs for specific version after it was first released - bugfix: - mode: ContinuousDeployment - label: '{BranchName}' - increment: Inherit - regex: ^bugfix?[/-](?.+) - tracks-release-branches: true - source-branches: - - support - # Feature branch - branch accumulates changes for specific version after it was first released - feature: - mode: ContinuousDeployment - label: '{BranchName}' - increment: Inherit - regex: ^feature?[/-](?.+) - tracks-release-branches: true - source-branches: - - preview - # PR branch - branch merges a source branch to a target branch - pull-request: - mode: ContinuousDeployment - label: pull-request - increment: Inherit - label-number-pattern: '[/-](?\d+)' - regex: ^(pull|pull\-requests|pr)[/-] - source-branches: - - main - - release - - preview - - hotfix - - support - - bugfix - - feature - # Main branch - branch tracks historical changes between releases - main: - mode: ManualDeployment - increment: Inherit - regex: ^main$ - tracks-release-branches: true - prevent-increment: - of-merged-branch: false - is-main-branch: true - source-branches: - - release - # Any other branch - unknown: - mode: ManualDeployment - label: '{BranchName}' - increment: Inherit - regex: (?.+) - source-branches: - - main - - release - - preview - - hotfix - - support - - bugfix - - feature - - pull-request diff --git a/.gitversion/version.yml b/.gitversion/version.yml index eae2db88..0f68f899 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,105 +1,126 @@ -next-version: 0.2.0.0 # -assembly-versioning-scheme: MajorMinorPatchTag -assembly-file-versioning-scheme: MajorMinorPatchTag -assembly-informational-format: "{FullSemVer}" -mode: ContinuousDeployment -increment: Inherit -continuous-delivery-fallback-tag: ci -tag-prefix: "[vV]" -major-version-bump-message: '\+semver:\s?(breaking|major)' -minor-version-bump-message: '\+semver:\s?(feature|minor)' -patch-version-bump-message: '\+semver:\s?(fix|patch)' -no-bump-message: '\+semver:\s?(none|skip)' -legacy-semver-padding: 4 -build-metadata-padding: 4 -commits-since-version-source-padding: 4 -commit-message-incrementing: Enabled -commit-date-format: "yyyy-MM-dd" +# Global settings +assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 42}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 42}' +tag-prefix: '[vV]?' +version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* +major-version-bump-message: '' +minor-version-bump-message: '' +patch-version-bump-message: '' +no-bump-message: '' +tag-pre-release-weight: 60000 +commit-date-format: yyyy-MM-dd +merge-message-formats: {} +update-build-number: false +semantic-version-format: Strict +strategies: +- VersionInBranchName +- TrackReleaseBranches +mode: ContinuousDelivery +label: '' +increment: Patch +prevent-increment: + of-merged-branch: true + when-branch-merged: true + when-current-commit-tagged: true +track-merge: + target: false + message: false +commit-message-incrementing: Disabled +regex: '' +source-branches: [] +is-source-branch-for: [] +tracks-release-branches: false +is-release-branch: false +is-main-branch: false ignore: sha: [] +# Branch settings branches: - main: - regex: ^master$|^main$ - mode: ContinuousDelivery - tag: '' - increment: Patch - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'develop', 'release' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: true - pre-release-weight: 55000 - develop: - regex: ^dev(elop)?(ment)?$ - mode: ContinuousDeployment - tag: alpha - increment: Minor - prevent-increment-of-merged-branch-version: false - track-merge-target: true - source-branches: [] - tracks-release-branches: true - is-release-branch: false - is-mainline: false - pre-release-weight: 0 + # Release branch - branch tracks history for specific version release: - regex: ^release?[/-] - mode: ContinuousDelivery - tag: beta - increment: None - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'develop', 'main', 'support', 'release' ] - tracks-release-branches: false + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+) + increment: Inherit is-release-branch: true - is-mainline: false - pre-release-weight: 30000 + # Preview branch - branch accumulates changes for specific version before it is first released + preview: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+\/preview) + increment: Inherit + source-branches: + - release + # Hotfix branch - branch hotfixes a critical bug for specific version after it was first released + hotfix: + mode: ContinuousDeployment + label: '{BranchName}' + increment: Inherit + regex: ^hotfix?[/-](?.+) + tracks-release-branches: true + source-branches: + - release + # Support branch - branch accumulates changes for specific version after it was first released + support: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+\/support) + increment: Inherit + source-branches: + - release +# Bugfixes branch - branch hotfixes bugs for specific version after it was first released + bugfix: + mode: ContinuousDeployment + label: '{BranchName}' + increment: Inherit + regex: ^bugfix?[/-](?.+) + tracks-release-branches: true + source-branches: + - support + # Feature branch - branch accumulates changes for specific version after it was first released feature: - regex: ^feature?[/-] mode: ContinuousDeployment - tag: useBranchName + label: '{BranchName}' increment: Inherit - prevent-increment-of-merged-branch-version: false - track-merge-target: false - source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false - pre-release-weight: 30000 + regex: ^feature?[/-](?.+) + tracks-release-branches: true + source-branches: + - preview + # PR branch - branch merges a source branch to a target branch pull-request: + mode: ContinuousDeployment + label: pull-request + increment: Inherit + label-number-pattern: '[/-](?\d+)' regex: ^(pull|pull\-requests|pr)[/-] - mode: ContinuousDelivery - tag: PullRequest + source-branches: + - main + - release + - preview + - hotfix + - support + - bugfix + - feature + # Main branch - branch tracks historical changes between releases + main: + mode: ManualDeployment increment: Inherit - prevent-increment-of-merged-branch-version: false - tag-number-pattern: '[/-](?\d+)[-/]' - track-merge-target: false - source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false - pre-release-weight: 30000 - hotfix: - regex: ^hotfix(es)?[/-] - mode: ContinuousDelivery - tag: beta - increment: Patch - prevent-increment-of-merged-branch-version: false - track-merge-target: false - source-branches: [ 'develop', 'main', 'support' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false - pre-release-weight: 30000 - support: - regex: ^support[/-] - mode: ContinuousDelivery - tag: '' - increment: Patch - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'main' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: true - pre-release-weight: 55000 \ No newline at end of file + regex: ^main$ + tracks-release-branches: true + prevent-increment: + of-merged-branch: false + is-main-branch: true + source-branches: + - release + # Any other branch + unknown: + mode: ManualDeployment + label: '{BranchName}' + increment: Inherit + regex: (?.+) + source-branches: + - main + - release + - preview + - hotfix + - support + - bugfix + - feature + - pull-request From 3a14e2ec846d29f85c7553aef9a4e97034e5edce Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 21:41:03 +0100 Subject: [PATCH 217/352] sada --- .gitversion/version (2).yml | 124 +++++++++++++++++++++++++++ .gitversion/version.yml | 161 ++++++++++++++++++------------------ 2 files changed, 203 insertions(+), 82 deletions(-) create mode 100644 .gitversion/version (2).yml diff --git a/.gitversion/version (2).yml b/.gitversion/version (2).yml new file mode 100644 index 00000000..c8cbaa84 --- /dev/null +++ b/.gitversion/version (2).yml @@ -0,0 +1,124 @@ +# Global settings +assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 0}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 0}' +tag-prefix: '[vV]?' +version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* +major-version-bump-message: '' +minor-version-bump-message: '' +patch-version-bump-message: '' +no-bump-message: '' +tag-pre-release-weight: 60000 +commit-date-format: yyyy-MM-dd +merge-message-formats: {} +update-build-number: false +semantic-version-format: Strict +strategies: +- VersionInBranchName +- TrackReleaseBranches +mode: ContinuousDelivery +label: '' +increment: Patch +prevent-increment: + of-merged-branch: true + when-branch-merged: true + when-current-commit-tagged: true +track-merge: + target: false + message: false +commit-message-incrementing: Disabled +regex: '' +source-branches: [] +is-source-branch-for: [] +tracks-release-branches: false +is-release-branch: false +is-main-branch: false +ignore: + sha: [] +# Branch settings +branches: + # Release branch - branch tracks history for specific version + release: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+)$ + increment: Inherit + is-release-branch: true + # Preview branch - branch accumulates changes for specific version before it is first released + preview: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+\/preview)$ + increment: Inherit + source-branches: + - release + # Hotfix branch - branch hotfixes a critical bug for specific version after it was first released + hotfix: + mode: ContinuousDeployment + label: '{BranchName}' + increment: Inherit + regex: ^hotfix?[/-](?.+) + tracks-release-branches: true + source-branches: + - release + # Support branch - branch accumulates changes for specific version after it was first released + support: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+\/support)$ + increment: Inherit + source-branches: + - release +# Bugfixes branch - branch hotfixes bugs for specific version after it was first released + bugfix: + mode: ContinuousDeployment + label: '{BranchName}' + increment: Inherit + regex: ^bugfix?[/-](?.+) + tracks-release-branches: true + source-branches: + - support + # Feature branch - branch accumulates changes for specific version after it was first released + feature: + mode: ContinuousDeployment + label: '{BranchName}' + increment: Inherit + regex: ^feature?[/-](?.+)$ + tracks-release-branches: true + source-branches: + - preview + # PR branch - branch merges a source branch to a target branch + pull-request: + mode: ContinuousDeployment + label: pull-request + increment: Inherit + label-number-pattern: '[/-](?\d+)' + regex: ^(pull|pull\-requests|pr)[/-] + source-branches: + - main + - release + - preview + - hotfix + - support + - bugfix + - feature + # Main branch - branch tracks historical changes between releases + main: + mode: ManualDeployment + increment: Inherit + regex: ^main$ + tracks-release-branches: true + is-main-branch: true + source-branches: + - release + # Any other branch - branch tracks historical changes between releases + unknown: + mode: ManualDeployment + label: '{BranchName}' + increment: Inherit + regex: (?.+) + source-branches: + - main + - release + - preview + - hotfix + - support + - bugfix + - feature + - pull-request diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 0f68f899..5ec72c5b 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,6 +1,6 @@ # Global settings -assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 42}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 42}' +assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 0}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 0}' tag-prefix: '[vV]?' version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* major-version-bump-message: '' @@ -36,91 +36,88 @@ ignore: sha: [] # Branch settings branches: - # Release branch - branch tracks history for specific version - release: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+) - increment: Inherit - is-release-branch: true - # Preview branch - branch accumulates changes for specific version before it is first released - preview: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+\/preview) - increment: Inherit - source-branches: - - release - # Hotfix branch - branch hotfixes a critical bug for specific version after it was first released - hotfix: - mode: ContinuousDeployment - label: '{BranchName}' - increment: Inherit - regex: ^hotfix?[/-](?.+) - tracks-release-branches: true - source-branches: - - release - # Support branch - branch accumulates changes for specific version after it was first released - support: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+\/support) - increment: Inherit - source-branches: - - release -# Bugfixes branch - branch hotfixes bugs for specific version after it was first released - bugfix: + main: + regex: ^master$|^main$ + mode: ContinuousDelivery + tag: '' + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'develop', 'release' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: true + pre-release-weight: 55000 + develop: + regex: ^dev(elop)?(ment)?$ mode: ContinuousDeployment - label: '{BranchName}' - increment: Inherit - regex: ^bugfix?[/-](?.+) + tag: alpha + increment: Minor + prevent-increment-of-merged-branch-version: false + track-merge-target: true + source-branches: [] tracks-release-branches: true - source-branches: - - support - # Feature branch - branch accumulates changes for specific version after it was first released + is-release-branch: false + is-mainline: false + pre-release-weight: 0 + release: + regex: ^release?[/-] + mode: ContinuousDelivery + tag: beta + increment: None + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'develop', 'main', 'support', 'release' ] + tracks-release-branches: false + is-release-branch: true + is-mainline: false + pre-release-weight: 30000 feature: + regex: ^feature?[/-] mode: ContinuousDeployment - label: '{BranchName}' + tag: useBranchName increment: Inherit - regex: ^feature?[/-](?.+) - tracks-release-branches: true - source-branches: - - preview - # PR branch - branch merges a source branch to a target branch + prevent-increment-of-merged-branch-version: false + track-merge-target: false + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 pull-request: - mode: ContinuousDeployment - label: pull-request - increment: Inherit - label-number-pattern: '[/-](?\d+)' regex: ^(pull|pull\-requests|pr)[/-] - source-branches: - - main - - release - - preview - - hotfix - - support - - bugfix - - feature - # Main branch - branch tracks historical changes between releases - main: - mode: ManualDeployment - increment: Inherit - regex: ^main$ - tracks-release-branches: true - prevent-increment: - of-merged-branch: false - is-main-branch: true - source-branches: - - release - # Any other branch - unknown: - mode: ManualDeployment - label: '{BranchName}' + mode: ContinuousDelivery + tag: PullRequest increment: Inherit - regex: (?.+) - source-branches: - - main - - release - - preview - - hotfix - - support - - bugfix - - feature - - pull-request + prevent-increment-of-merged-branch-version: false + tag-number-pattern: '[/-](?\d+)[-/]' + track-merge-target: false + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 + hotfix: + regex: ^hotfix(es)?[/-] + mode: ContinuousDelivery + tag: beta + increment: Patch + prevent-increment-of-merged-branch-version: false + track-merge-target: false + source-branches: [ 'develop', 'main', 'support' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 + support: + regex: ^support[/-] + mode: ContinuousDelivery + tag: '' + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'main' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: true + pre-release-weight: 55000 \ No newline at end of file From 070cc7d0e5b87565e6807d56e553f50b92996dfe Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 22:22:04 +0100 Subject: [PATCH 218/352] gfgsd --- .gitversion/version.yml | 147 +++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 77 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 5ec72c5b..bfd27f28 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -36,88 +36,81 @@ ignore: sha: [] # Branch settings branches: - main: - regex: ^master$|^main$ - mode: ContinuousDelivery - tag: '' - increment: Patch - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'develop', 'release' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: true - pre-release-weight: 55000 - develop: - regex: ^dev(elop)?(ment)?$ - mode: ContinuousDeployment - tag: alpha - increment: Minor - prevent-increment-of-merged-branch-version: false - track-merge-target: true - source-branches: [] - tracks-release-branches: true - is-release-branch: false - is-mainline: false - pre-release-weight: 0 + # Release branch - branch tracks history for specific version release: - regex: ^release?[/-] - mode: ContinuousDelivery - tag: beta - increment: None - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'develop', 'main', 'support', 'release' ] - tracks-release-branches: false + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+)$ + increment: Inherit is-release-branch: true - is-mainline: false - pre-release-weight: 30000 + # Preview branch - branch accumulates changes for specific version before it is first released + preview: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+\/preview)$ + increment: Inherit + source-branches: + - release + # Hotfix branch - branch hotfixes a critical bug for specific version after it was first released + hotfix: + mode: ContinuousDeployment + label: '{BranchName}' + increment: Inherit + regex: ^hotfix?[/-](?.+) + tracks-release-branches: true + source-branches: + - release + # Support branch - branch accumulates changes for specific version after it was first released + support: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+\/support)$ + increment: Inherit + source-branches: + - release +# Bugfixes branch - branch hotfixes bugs for specific version after it was first released + bugfix: + mode: ContinuousDeployment + label: '{BranchName}' + increment: Inherit + regex: ^bugfix?[/-](?.+) + tracks-release-branches: true + source-branches: + - support + # Feature branch - branch accumulates changes for specific version after it was first released feature: - regex: ^feature?[/-] mode: ContinuousDeployment - tag: useBranchName + label: '{BranchName}' increment: Inherit - prevent-increment-of-merged-branch-version: false - track-merge-target: false - source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false - pre-release-weight: 30000 + regex: ^feature?[/-](?.+)$ + tracks-release-branches: true + source-branches: + - preview + # PR branch - branch merges a source branch to a target branch pull-request: + mode: ContinuousDeployment + label: pull-request + increment: Inherit + label-number-pattern: '[/-](?\d+)' regex: ^(pull|pull\-requests|pr)[/-] - mode: ContinuousDelivery - tag: PullRequest + source-branches: + - main + - release + - preview + - hotfix + - support + - bugfix + - feature + # Main branch - branch tracks historical changes between releases + main: + mode: ManualDeployment increment: Inherit - prevent-increment-of-merged-branch-version: false - tag-number-pattern: '[/-](?\d+)[-/]' - track-merge-target: false - source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false - pre-release-weight: 30000 - hotfix: - regex: ^hotfix(es)?[/-] - mode: ContinuousDelivery - tag: beta - increment: Patch - prevent-increment-of-merged-branch-version: false - track-merge-target: false - source-branches: [ 'develop', 'main', 'support' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false - pre-release-weight: 30000 - support: - regex: ^support[/-] - mode: ContinuousDelivery - tag: '' - increment: Patch - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'main' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: true - pre-release-weight: 55000 \ No newline at end of file + regex: ^main$ + tracks-release-branches: true + is-main-branch: true + source-branches: + - release + # Any other branch - branch tracks historical changes between releases + unknown: + mode: ManualDeployment + label: '{BranchName}' + increment: Inherit + regex: (?.+) + source-branches: [ 'main', 'release', 'preview', 'hotfix', 'support', 'support', 'bugfix', 'feature', 'pull-request' ] From 288531ebd1198a2f355347a6958e1423e4609371 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 22:24:08 +0100 Subject: [PATCH 219/352] dsfgsfrw --- .gitversion/version.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index bfd27f28..1c5edbf3 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,6 +1,7 @@ # Global settings -assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 0}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 0}' +assembly-versioning-format: MajorMinorPatchTag +assembly-file-versioning-format: MajorMinorPatchTag +assembly-informational-format: "{FullSemVer}" tag-prefix: '[vV]?' version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* major-version-bump-message: '' @@ -113,4 +114,12 @@ branches: label: '{BranchName}' increment: Inherit regex: (?.+) - source-branches: [ 'main', 'release', 'preview', 'hotfix', 'support', 'support', 'bugfix', 'feature', 'pull-request' ] + source-branches: + - main + - release + - preview + - hotfix + - support + - bugfix + - feature + - pull-request From 329af437fc3abdb5f8e211ea596975109666d10c Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 22:25:03 +0100 Subject: [PATCH 220/352] sdffwe --- .gitversion/version (2).yml | 5 +- .gitversion/version.yml | 206 ++++++++++++++++-------------------- 2 files changed, 96 insertions(+), 115 deletions(-) diff --git a/.gitversion/version (2).yml b/.gitversion/version (2).yml index c8cbaa84..1c5edbf3 100644 --- a/.gitversion/version (2).yml +++ b/.gitversion/version (2).yml @@ -1,6 +1,7 @@ # Global settings -assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 0}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 0}' +assembly-versioning-format: MajorMinorPatchTag +assembly-file-versioning-format: MajorMinorPatchTag +assembly-informational-format: "{FullSemVer}" tag-prefix: '[vV]?' version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* major-version-bump-message: '' diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 1c5edbf3..eae2db88 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,125 +1,105 @@ -# Global settings -assembly-versioning-format: MajorMinorPatchTag -assembly-file-versioning-format: MajorMinorPatchTag +next-version: 0.2.0.0 # +assembly-versioning-scheme: MajorMinorPatchTag +assembly-file-versioning-scheme: MajorMinorPatchTag assembly-informational-format: "{FullSemVer}" -tag-prefix: '[vV]?' -version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* -major-version-bump-message: '' -minor-version-bump-message: '' -patch-version-bump-message: '' -no-bump-message: '' -tag-pre-release-weight: 60000 -commit-date-format: yyyy-MM-dd -merge-message-formats: {} -update-build-number: false -semantic-version-format: Strict -strategies: -- VersionInBranchName -- TrackReleaseBranches -mode: ContinuousDelivery -label: '' -increment: Patch -prevent-increment: - of-merged-branch: true - when-branch-merged: true - when-current-commit-tagged: true -track-merge: - target: false - message: false -commit-message-incrementing: Disabled -regex: '' -source-branches: [] -is-source-branch-for: [] -tracks-release-branches: false -is-release-branch: false -is-main-branch: false +mode: ContinuousDeployment +increment: Inherit +continuous-delivery-fallback-tag: ci +tag-prefix: "[vV]" +major-version-bump-message: '\+semver:\s?(breaking|major)' +minor-version-bump-message: '\+semver:\s?(feature|minor)' +patch-version-bump-message: '\+semver:\s?(fix|patch)' +no-bump-message: '\+semver:\s?(none|skip)' +legacy-semver-padding: 4 +build-metadata-padding: 4 +commits-since-version-source-padding: 4 +commit-message-incrementing: Enabled +commit-date-format: "yyyy-MM-dd" ignore: sha: [] -# Branch settings branches: - # Release branch - branch tracks history for specific version - release: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+)$ - increment: Inherit - is-release-branch: true - # Preview branch - branch accumulates changes for specific version before it is first released - preview: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+\/preview)$ - increment: Inherit - source-branches: - - release - # Hotfix branch - branch hotfixes a critical bug for specific version after it was first released - hotfix: - mode: ContinuousDeployment - label: '{BranchName}' - increment: Inherit - regex: ^hotfix?[/-](?.+) - tracks-release-branches: true - source-branches: - - release - # Support branch - branch accumulates changes for specific version after it was first released - support: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+\/support)$ - increment: Inherit - source-branches: - - release -# Bugfixes branch - branch hotfixes bugs for specific version after it was first released - bugfix: + main: + regex: ^master$|^main$ + mode: ContinuousDelivery + tag: '' + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'develop', 'release' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: true + pre-release-weight: 55000 + develop: + regex: ^dev(elop)?(ment)?$ mode: ContinuousDeployment - label: '{BranchName}' - increment: Inherit - regex: ^bugfix?[/-](?.+) + tag: alpha + increment: Minor + prevent-increment-of-merged-branch-version: false + track-merge-target: true + source-branches: [] tracks-release-branches: true - source-branches: - - support - # Feature branch - branch accumulates changes for specific version after it was first released + is-release-branch: false + is-mainline: false + pre-release-weight: 0 + release: + regex: ^release?[/-] + mode: ContinuousDelivery + tag: beta + increment: None + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'develop', 'main', 'support', 'release' ] + tracks-release-branches: false + is-release-branch: true + is-mainline: false + pre-release-weight: 30000 feature: + regex: ^feature?[/-] mode: ContinuousDeployment - label: '{BranchName}' + tag: useBranchName increment: Inherit - regex: ^feature?[/-](?.+)$ - tracks-release-branches: true - source-branches: - - preview - # PR branch - branch merges a source branch to a target branch + prevent-increment-of-merged-branch-version: false + track-merge-target: false + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 pull-request: - mode: ContinuousDeployment - label: pull-request - increment: Inherit - label-number-pattern: '[/-](?\d+)' regex: ^(pull|pull\-requests|pr)[/-] - source-branches: - - main - - release - - preview - - hotfix - - support - - bugfix - - feature - # Main branch - branch tracks historical changes between releases - main: - mode: ManualDeployment - increment: Inherit - regex: ^main$ - tracks-release-branches: true - is-main-branch: true - source-branches: - - release - # Any other branch - branch tracks historical changes between releases - unknown: - mode: ManualDeployment - label: '{BranchName}' + mode: ContinuousDelivery + tag: PullRequest increment: Inherit - regex: (?.+) - source-branches: - - main - - release - - preview - - hotfix - - support - - bugfix - - feature - - pull-request + prevent-increment-of-merged-branch-version: false + tag-number-pattern: '[/-](?\d+)[-/]' + track-merge-target: false + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 + hotfix: + regex: ^hotfix(es)?[/-] + mode: ContinuousDelivery + tag: beta + increment: Patch + prevent-increment-of-merged-branch-version: false + track-merge-target: false + source-branches: [ 'develop', 'main', 'support' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 + support: + regex: ^support[/-] + mode: ContinuousDelivery + tag: '' + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'main' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: true + pre-release-weight: 55000 \ No newline at end of file From 209594535d0ada6d8d43b8a3c94515f9f9c1c214 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 22:26:53 +0100 Subject: [PATCH 221/352] fdgdfe --- .gitversion/version.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index eae2db88..523bf787 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,19 +1,19 @@ +mode: ContinuousDeployment next-version: 0.2.0.0 # assembly-versioning-scheme: MajorMinorPatchTag assembly-file-versioning-scheme: MajorMinorPatchTag assembly-informational-format: "{FullSemVer}" -mode: ContinuousDeployment -increment: Inherit +increment: Patch continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" -major-version-bump-message: '\+semver:\s?(breaking|major)' -minor-version-bump-message: '\+semver:\s?(feature|minor)' -patch-version-bump-message: '\+semver:\s?(fix|patch)' -no-bump-message: '\+semver:\s?(none|skip)' +major-version-bump-message: '' +minor-version-bump-message: '' +patch-version-bump-message: '' +no-bump-message: '' legacy-semver-padding: 4 build-metadata-padding: 4 commits-since-version-source-padding: 4 -commit-message-incrementing: Enabled +commit-message-incrementing: Disabled commit-date-format: "yyyy-MM-dd" ignore: sha: [] From ca3b4ad3a00588f1b4d81ce1214f4044d32f0308 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 22:29:46 +0100 Subject: [PATCH 222/352] cxczfsd --- .gitversion/version.yml | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 523bf787..7fff941f 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -15,9 +15,18 @@ build-metadata-padding: 4 commits-since-version-source-padding: 4 commit-message-incrementing: Disabled commit-date-format: "yyyy-MM-dd" +prevent-increment-of-merged-branch-version: true +track-merge-target: false +tracks-release-branches: false +is-release-branch: false +is-mainline: false ignore: sha: [] branches: + release: + regex: ^release?[/-] + source-branches: [ 'develop', 'main', 'support', 'release' ] + is-release-branch: true main: regex: ^master$|^main$ mode: ContinuousDelivery @@ -42,18 +51,6 @@ branches: is-release-branch: false is-mainline: false pre-release-weight: 0 - release: - regex: ^release?[/-] - mode: ContinuousDelivery - tag: beta - increment: None - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'develop', 'main', 'support', 'release' ] - tracks-release-branches: false - is-release-branch: true - is-mainline: false - pre-release-weight: 30000 feature: regex: ^feature?[/-] mode: ContinuousDeployment From 282de191e3753a6764e8ef83422d54ae58783839 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 22:32:04 +0100 Subject: [PATCH 223/352] jyfjyf --- .gitversion/version.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 7fff941f..105718ce 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -15,18 +15,18 @@ build-metadata-padding: 4 commits-since-version-source-padding: 4 commit-message-incrementing: Disabled commit-date-format: "yyyy-MM-dd" -prevent-increment-of-merged-branch-version: true -track-merge-target: false -tracks-release-branches: false -is-release-branch: false -is-mainline: false ignore: sha: [] branches: release: regex: ^release?[/-] + prevent-increment-of-merged-branch-version: true + track-merge-target: false source-branches: [ 'develop', 'main', 'support', 'release' ] + tracks-release-branches: false is-release-branch: true + is-mainline: false + pre-release-weight: 30000 main: regex: ^master$|^main$ mode: ContinuousDelivery From 364c25218e9fa067edbdc3003ef38158cad63c51 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 22:33:52 +0100 Subject: [PATCH 224/352] xzcds --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 09f9761b..e032ecf1 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -63,7 +63,7 @@ jobs: with: dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Test with .NET ${{ vars.DOTNET_VERSION }} - run: dotnet test ./tests/**/*Tests.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} --verbosity normal --settings unit-test.runsettings --logger trx --collect:Code Coverage --results-directory test-results + run: dotnet test --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} --verbosity normal --settings unit-test.runsettings --logger trx --collect:Code Coverage --results-directory test-results - name: Upload Test Results uses: actions/upload-artifact@v4 with: From d7988488b40fa7089814e26bd697b8484a40b865 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 22:41:30 +0100 Subject: [PATCH 225/352] dfsfgrs --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index e032ecf1..97d62e0c 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -63,7 +63,7 @@ jobs: with: dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Test with .NET ${{ vars.DOTNET_VERSION }} - run: dotnet test --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} --verbosity normal --settings unit-test.runsettings --logger trx --collect:Code Coverage --results-directory test-results + run: dotnet test --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} --verbosity normal --settings unit-test.runsettings --logger trx --collect:'Code Coverage' --results-directory test-results - name: Upload Test Results uses: actions/upload-artifact@v4 with: From d3d777efe5dd14fbf079a634658407679978fc26 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 22:43:59 +0100 Subject: [PATCH 226/352] xcsfvd --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 97d62e0c..2a2a760a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -63,7 +63,7 @@ jobs: with: dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Test with .NET ${{ vars.DOTNET_VERSION }} - run: dotnet test --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} --verbosity normal --settings unit-test.runsettings --logger trx --collect:'Code Coverage' --results-directory test-results + run: dotnet test ./tests/**/*Tests.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} --verbosity normal --settings unit-test.runsettings --logger trx --collect:"Code Coverage" --results-directory test-results - name: Upload Test Results uses: actions/upload-artifact@v4 with: From 9aba977740aa7e62e205919bca167fd08e78580c Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 22:47:11 +0100 Subject: [PATCH 227/352] fxgsf --- .gitversion/version.yml | 148 +++++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 72 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 105718ce..877b4ca2 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -18,85 +18,89 @@ commit-date-format: "yyyy-MM-dd" ignore: sha: [] branches: + # Release branch - branch tracks history for specific version release: - regex: ^release?[/-] - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'develop', 'main', 'support', 'release' ] - tracks-release-branches: false + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+)$ + increment: Inherit is-release-branch: true - is-mainline: false - pre-release-weight: 30000 - main: - regex: ^master$|^main$ - mode: ContinuousDelivery - tag: '' - increment: Patch - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'develop', 'release' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: true - pre-release-weight: 55000 - develop: - regex: ^dev(elop)?(ment)?$ + # Preview branch - branch accumulates changes for specific version before it is first released + preview: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+\/preview)$ + increment: Inherit + source-branches: + - release + # Hotfix branch - branch hotfixes a critical bug for specific version after it was first released + hotfix: mode: ContinuousDeployment - tag: alpha - increment: Minor - prevent-increment-of-merged-branch-version: false - track-merge-target: true - source-branches: [] + label: '{BranchName}' + increment: Inherit + regex: ^hotfix?[/-](?.+) tracks-release-branches: true - is-release-branch: false - is-mainline: false - pre-release-weight: 0 + source-branches: + - release + # Support branch - branch accumulates changes for specific version after it was first released + support: + mode: ContinuousDeployment + regex: ^(release[\/][\d]+\.[\d]+\/support)$ + increment: Inherit + source-branches: + - release +# Bugfixes branch - branch hotfixes bugs for specific version after it was first released + bugfix: + mode: ContinuousDeployment + label: '{BranchName}' + increment: Inherit + regex: ^bugfix?[/-](?.+) + tracks-release-branches: true + source-branches: + - support + # Feature branch - branch accumulates changes for specific version after it was first released feature: - regex: ^feature?[/-] mode: ContinuousDeployment - tag: useBranchName + label: '{BranchName}' increment: Inherit - prevent-increment-of-merged-branch-version: false - track-merge-target: false - source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false - pre-release-weight: 30000 + regex: ^feature?[/-](?.+)$ + tracks-release-branches: true + source-branches: + - preview + # PR branch - branch merges a source branch to a target branch pull-request: + mode: ContinuousDeployment + label: pull-request + increment: Inherit + label-number-pattern: '[/-](?\d+)' regex: ^(pull|pull\-requests|pr)[/-] - mode: ContinuousDelivery - tag: PullRequest + source-branches: + - main + - release + - preview + - hotfix + - support + - bugfix + - feature + # Main branch - branch tracks historical changes between releases + main: + mode: ManualDeployment increment: Inherit - prevent-increment-of-merged-branch-version: false - tag-number-pattern: '[/-](?\d+)[-/]' - track-merge-target: false - source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false - pre-release-weight: 30000 - hotfix: - regex: ^hotfix(es)?[/-] - mode: ContinuousDelivery - tag: beta - increment: Patch - prevent-increment-of-merged-branch-version: false - track-merge-target: false - source-branches: [ 'develop', 'main', 'support' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false - pre-release-weight: 30000 - support: - regex: ^support[/-] - mode: ContinuousDelivery - tag: '' - increment: Patch - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'main' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: true - pre-release-weight: 55000 \ No newline at end of file + regex: ^main$ + tracks-release-branches: true + is-main-branch: true + source-branches: + - release + # Any other branch - branch tracks historical changes between releases + unknown: + mode: ManualDeployment + label: '{BranchName}' + increment: Inherit + regex: (?.+) + source-branches: + - main + - release + - preview + - hotfix + - support + - bugfix + - feature + - pull-request \ No newline at end of file From b87e721f0de6f8ce44c1b4760be646a178cc596c Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 23:38:16 +0100 Subject: [PATCH 228/352] xsgdfgfw --- .gitversion/version.yml | 180 +++++++++++++++++++++------------------- 1 file changed, 93 insertions(+), 87 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 877b4ca2..1a8277ea 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,106 +1,112 @@ mode: ContinuousDeployment -next-version: 0.2.0.0 # assembly-versioning-scheme: MajorMinorPatchTag assembly-file-versioning-scheme: MajorMinorPatchTag assembly-informational-format: "{FullSemVer}" -increment: Patch continuous-delivery-fallback-tag: ci -tag-prefix: "[vV]" -major-version-bump-message: '' -minor-version-bump-message: '' -patch-version-bump-message: '' -no-bump-message: '' -legacy-semver-padding: 4 + +next-version: 0.9.0.0 # +increment: Inherit + build-metadata-padding: 4 +legacy-semver-padding: 4 + +tag-prefix: "[vV]" +major-version-bump-message: '\+semver:\s?(breaking|major)' +minor-version-bump-message: '\+semver:\s?(feature|minor)' +patch-version-bump-message: '\+semver:\s?(fix|patch)' +no-bump-message: '\+semver:\s?(none|skip)' + + commits-since-version-source-padding: 4 -commit-message-incrementing: Disabled +commit-message-incrementing: Enabled commit-date-format: "yyyy-MM-dd" + ignore: sha: [] + branches: - # Release branch - branch tracks history for specific version - release: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+)$ - increment: Inherit - is-release-branch: true - # Preview branch - branch accumulates changes for specific version before it is first released - preview: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+\/preview)$ - increment: Inherit - source-branches: - - release - # Hotfix branch - branch hotfixes a critical bug for specific version after it was first released - hotfix: - mode: ContinuousDeployment - label: '{BranchName}' - increment: Inherit - regex: ^hotfix?[/-](?.+) - tracks-release-branches: true - source-branches: - - release - # Support branch - branch accumulates changes for specific version after it was first released - support: - mode: ContinuousDeployment - regex: ^(release[\/][\d]+\.[\d]+\/support)$ - increment: Inherit - source-branches: - - release -# Bugfixes branch - branch hotfixes bugs for specific version after it was first released - bugfix: + main: + regex: ^master$|^main$ + mode: ContinuousDelivery + tag: '' + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'develop', 'release' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: true + pre-release-weight: 55000 + develop: + regex: ^dev(elop)?(ment)?$ mode: ContinuousDeployment - label: '{BranchName}' - increment: Inherit - regex: ^bugfix?[/-](?.+) + tag: alpha + increment: Minor + prevent-increment-of-merged-branch-version: false + track-merge-target: true + source-branches: [] tracks-release-branches: true - source-branches: - - support - # Feature branch - branch accumulates changes for specific version after it was first released + is-release-branch: false + is-mainline: false + pre-release-weight: 0 + release: + regex: ^release?[/-] + mode: ContinuousDelivery + tag: beta + increment: None + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'develop', 'main', 'support', 'release' ] + tracks-release-branches: false + is-release-branch: true + is-mainline: false + pre-release-weight: 30000 feature: + regex: ^feature?[/-] mode: ContinuousDeployment - label: '{BranchName}' + tag: useBranchName increment: Inherit - regex: ^feature?[/-](?.+)$ - tracks-release-branches: true - source-branches: - - preview - # PR branch - branch merges a source branch to a target branch + prevent-increment-of-merged-branch-version: false + track-merge-target: false + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 pull-request: - mode: ContinuousDeployment - label: pull-request - increment: Inherit - label-number-pattern: '[/-](?\d+)' regex: ^(pull|pull\-requests|pr)[/-] - source-branches: - - main - - release - - preview - - hotfix - - support - - bugfix - - feature - # Main branch - branch tracks historical changes between releases - main: - mode: ManualDeployment + mode: ContinuousDelivery + tag: PullRequest increment: Inherit - regex: ^main$ - tracks-release-branches: true - is-main-branch: true - source-branches: - - release - # Any other branch - branch tracks historical changes between releases - unknown: - mode: ManualDeployment - label: '{BranchName}' - increment: Inherit - regex: (?.+) - source-branches: - - main - - release - - preview - - hotfix - - support - - bugfix - - feature - - pull-request \ No newline at end of file + prevent-increment-of-merged-branch-version: false + tag-number-pattern: '[/-](?\d+)[-/]' + track-merge-target: false + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 + hotfix: + regex: ^hotfix(es)?[/-] + mode: ContinuousDelivery + tag: beta + increment: Patch + prevent-increment-of-merged-branch-version: false + track-merge-target: false + source-branches: [ 'develop', 'main', 'support' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 + support: + regex: ^support[/-] + mode: ContinuousDelivery + tag: '' + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'main' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: true + pre-release-weight: 55000 \ No newline at end of file From 50b23ccdda2ea4503c5e76d39d06619c9cdc3242 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 23:40:04 +0100 Subject: [PATCH 229/352] dfsgdfer --- .gitversion/version.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 1a8277ea..b59e0df6 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -4,19 +4,19 @@ assembly-file-versioning-scheme: MajorMinorPatchTag assembly-informational-format: "{FullSemVer}" continuous-delivery-fallback-tag: ci -next-version: 0.9.0.0 # increment: Inherit +next-version: 0.9.0.0 # +tag-prefix: "[vV]" build-metadata-padding: 4 legacy-semver-padding: 4 -tag-prefix: "[vV]" + major-version-bump-message: '\+semver:\s?(breaking|major)' minor-version-bump-message: '\+semver:\s?(feature|minor)' patch-version-bump-message: '\+semver:\s?(fix|patch)' no-bump-message: '\+semver:\s?(none|skip)' - commits-since-version-source-padding: 4 commit-message-incrementing: Enabled commit-date-format: "yyyy-MM-dd" @@ -25,6 +25,7 @@ ignore: sha: [] branches: + main: regex: ^master$|^main$ mode: ContinuousDelivery @@ -37,6 +38,7 @@ branches: is-release-branch: false is-mainline: true pre-release-weight: 55000 + develop: regex: ^dev(elop)?(ment)?$ mode: ContinuousDeployment @@ -49,6 +51,7 @@ branches: is-release-branch: false is-mainline: false pre-release-weight: 0 + release: regex: ^release?[/-] mode: ContinuousDelivery @@ -61,6 +64,7 @@ branches: is-release-branch: true is-mainline: false pre-release-weight: 30000 + feature: regex: ^feature?[/-] mode: ContinuousDeployment @@ -73,6 +77,7 @@ branches: is-release-branch: false is-mainline: false pre-release-weight: 30000 + pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery @@ -86,6 +91,7 @@ branches: is-release-branch: false is-mainline: false pre-release-weight: 30000 + hotfix: regex: ^hotfix(es)?[/-] mode: ContinuousDelivery @@ -98,6 +104,7 @@ branches: is-release-branch: false is-mainline: false pre-release-weight: 30000 + support: regex: ^support[/-] mode: ContinuousDelivery From f290114c17a0cb59665f8df4e81bd54fcaffbd25 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 23:42:42 +0100 Subject: [PATCH 230/352] zxcz --- .gitversion/version.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index b59e0df6..14553a0d 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,17 +1,17 @@ mode: ContinuousDeployment + assembly-versioning-scheme: MajorMinorPatchTag assembly-file-versioning-scheme: MajorMinorPatchTag assembly-informational-format: "{FullSemVer}" -continuous-delivery-fallback-tag: ci increment: Inherit next-version: 0.9.0.0 # tag-prefix: "[vV]" +continuous-delivery-fallback-tag: ci build-metadata-padding: 4 legacy-semver-padding: 4 - major-version-bump-message: '\+semver:\s?(breaking|major)' minor-version-bump-message: '\+semver:\s?(feature|minor)' patch-version-bump-message: '\+semver:\s?(fix|patch)' @@ -28,7 +28,7 @@ branches: main: regex: ^master$|^main$ - mode: ContinuousDelivery + mode: ManualDeployment tag: '' increment: Patch prevent-increment-of-merged-branch-version: true From 8752ca00a878b63433fcab3e05a0ef3b8073e5a2 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 23:51:24 +0100 Subject: [PATCH 231/352] Revert "zxcz" This reverts commit f290114c17a0cb59665f8df4e81bd54fcaffbd25. --- .gitversion/version.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 14553a0d..b59e0df6 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,17 +1,17 @@ mode: ContinuousDeployment - assembly-versioning-scheme: MajorMinorPatchTag assembly-file-versioning-scheme: MajorMinorPatchTag assembly-informational-format: "{FullSemVer}" +continuous-delivery-fallback-tag: ci increment: Inherit next-version: 0.9.0.0 # tag-prefix: "[vV]" -continuous-delivery-fallback-tag: ci build-metadata-padding: 4 legacy-semver-padding: 4 + major-version-bump-message: '\+semver:\s?(breaking|major)' minor-version-bump-message: '\+semver:\s?(feature|minor)' patch-version-bump-message: '\+semver:\s?(fix|patch)' @@ -28,7 +28,7 @@ branches: main: regex: ^master$|^main$ - mode: ManualDeployment + mode: ContinuousDelivery tag: '' increment: Patch prevent-increment-of-merged-branch-version: true From eefa1280920b7b9e8183fdd1e216f661371b322b Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 23:53:15 +0100 Subject: [PATCH 232/352] xzcd --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index b59e0df6..46df92a5 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -28,7 +28,7 @@ branches: main: regex: ^master$|^main$ - mode: ContinuousDelivery + mode: ContinuousIntegration tag: '' increment: Patch prevent-increment-of-merged-branch-version: true From 4152a4a9743d3ab33666591f1283ed148b5177f9 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 23:54:13 +0100 Subject: [PATCH 233/352] zdfsvd --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 46df92a5..9371a9c0 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -28,7 +28,7 @@ branches: main: regex: ^master$|^main$ - mode: ContinuousIntegration + mode: ContinuousDeployment tag: '' increment: Patch prevent-increment-of-merged-branch-version: true From e8576f17082a09b5bcd296a880ddd8021505ebef Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 23:56:13 +0100 Subject: [PATCH 234/352] xzcvxfsd --- .gitversion/version.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 9371a9c0..29e68d4e 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,17 +1,18 @@ mode: ContinuousDeployment + assembly-versioning-scheme: MajorMinorPatchTag assembly-file-versioning-scheme: MajorMinorPatchTag assembly-informational-format: "{FullSemVer}" -continuous-delivery-fallback-tag: ci increment: Inherit next-version: 0.9.0.0 # + +continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" build-metadata-padding: 4 legacy-semver-padding: 4 - major-version-bump-message: '\+semver:\s?(breaking|major)' minor-version-bump-message: '\+semver:\s?(feature|minor)' patch-version-bump-message: '\+semver:\s?(fix|patch)' @@ -28,7 +29,7 @@ branches: main: regex: ^master$|^main$ - mode: ContinuousDeployment + mode: ContinuousDelivery tag: '' increment: Patch prevent-increment-of-merged-branch-version: true From 7ef696f3a0b7a73ec6dfe0d22bf49aa3852372b5 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Sun, 2 Feb 2025 23:59:04 +0100 Subject: [PATCH 235/352] kzhfsd --- .github/workflows/dotnet.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 2a2a760a..7f2d1ed0 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -2,11 +2,13 @@ name: .NET on: push: - branches: - - '**' + branches-ignore: + - 'main' + - 'release/**' pull_request: branches: - - '**' + - 'main' + - 'release/**' concurrency: ${{ github.ref }} From 26e7583c2e67dec82cf2964911b8a53417c97191 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 00:00:38 +0100 Subject: [PATCH 236/352] kjhh --- .github/workflows/dotnet.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 7f2d1ed0..32a33a47 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -1,10 +1,6 @@ name: .NET on: - push: - branches-ignore: - - 'main' - - 'release/**' pull_request: branches: - 'main' From 5968095149da7119c9822686b8968574db0c18be Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 00:03:02 +0100 Subject: [PATCH 237/352] hiu --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 29e68d4e..8b768ace 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -4,7 +4,7 @@ assembly-versioning-scheme: MajorMinorPatchTag assembly-file-versioning-scheme: MajorMinorPatchTag assembly-informational-format: "{FullSemVer}" -increment: Inherit +increment: Patch next-version: 0.9.0.0 # continuous-delivery-fallback-tag: ci From f5b8b8b45b0cdf9dcc234dfe4fba03e87071e2ee Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 00:05:30 +0100 Subject: [PATCH 238/352] kgk --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 8b768ace..8e4ac292 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -82,7 +82,7 @@ branches: pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery - tag: PullRequest + tag: PR-{number}-beta increment: Inherit prevent-increment-of-merged-branch-version: false tag-number-pattern: '[/-](?\d+)[-/]' From 1b8203eaf4bbf69e9856df51340aefbb85d5fa80 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 00:08:33 +0100 Subject: [PATCH 239/352] zxfsd --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 8e4ac292..d854c68e 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -82,7 +82,7 @@ branches: pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery - tag: PR-{number}-beta + tag: PR- increment: Inherit prevent-increment-of-merged-branch-version: false tag-number-pattern: '[/-](?\d+)[-/]' From eb2b186549b52e60c94e692c73a61846b57e48b5 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 00:11:21 +0100 Subject: [PATCH 240/352] kjhkjh --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index d854c68e..0c749ed3 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -10,8 +10,8 @@ next-version: 0.9.0.0 # continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" -build-metadata-padding: 4 -legacy-semver-padding: 4 +build-metadata-padding: 0 +legacy-semver-padding: 0 major-version-bump-message: '\+semver:\s?(breaking|major)' minor-version-bump-message: '\+semver:\s?(feature|minor)' From 9049ab05e9154f15198016f7d554d38b6ae54ec6 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 00:18:42 +0100 Subject: [PATCH 241/352] skzjhadsk --- .gitversion/version (2).yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version (2).yml b/.gitversion/version (2).yml index 1c5edbf3..d8aaeb61 100644 --- a/.gitversion/version (2).yml +++ b/.gitversion/version (2).yml @@ -1,6 +1,6 @@ # Global settings -assembly-versioning-format: MajorMinorPatchTag -assembly-file-versioning-format: MajorMinorPatchTag +assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' assembly-informational-format: "{FullSemVer}" tag-prefix: '[vV]?' version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* From c308ee9e5e808e118baf3aad8ff0e200f4d50e97 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 00:20:32 +0100 Subject: [PATCH 242/352] jhgj --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 0c749ed3..05d2012d 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -82,7 +82,7 @@ branches: pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery - tag: PR- + tag: pr- increment: Inherit prevent-increment-of-merged-branch-version: false tag-number-pattern: '[/-](?\d+)[-/]' From 4e0312fd7f65308e5a9163a6d34dcdd386b553be Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 00:24:31 +0100 Subject: [PATCH 243/352] kjhkgi --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 05d2012d..e6d8a5c3 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,7 +1,7 @@ mode: ContinuousDeployment -assembly-versioning-scheme: MajorMinorPatchTag -assembly-file-versioning-scheme: MajorMinorPatchTag +assembly-versioning-format: '{Major}.{Minor}.{Patch}.{CommitsSinceVersionSource}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{CommitsSinceVersionSource}' assembly-informational-format: "{FullSemVer}" increment: Patch From 78806deb97e1f465f696a79fca8446cea221d262 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 00:32:10 +0100 Subject: [PATCH 244/352] kzgsfdias --- .gitversion/version.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index e6d8a5c3..8c366f95 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,11 +1,14 @@ mode: ContinuousDeployment +strategies: +- VersionInBranchName +- TrackReleaseBranches -assembly-versioning-format: '{Major}.{Minor}.{Patch}.{CommitsSinceVersionSource}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{CommitsSinceVersionSource}' +assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' assembly-informational-format: "{FullSemVer}" increment: Patch -next-version: 0.9.0.0 # +next-version: 0.9.0.0 continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" From 2029fe3a04f0b0162be8549dbe580c37cfacf993 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 00:42:44 +0100 Subject: [PATCH 245/352] jkhkh --- .gitversion/version.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 8c366f95..9d86d41c 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -8,7 +8,6 @@ assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' assembly-informational-format: "{FullSemVer}" increment: Patch -next-version: 0.9.0.0 continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" From 2b7ed6c1eeb84eada526c5900676ba823fa57a17 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 00:51:47 +0100 Subject: [PATCH 246/352] lhjl --- .gitversion/version.yml | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 9d86d41c..43d878c3 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -24,6 +24,20 @@ commits-since-version-source-padding: 4 commit-message-incrementing: Enabled commit-date-format: "yyyy-MM-dd" +is-release-branch: false +is-main-branch: false +is-mainline: false + +prevent-increment: + of-merged-branch-version: true + when-branch-merged: true + when-current-commit-tagged: true + +track-merge-target: false +track-merge-message: false +tracks-release-branches: false + + ignore: sha: [] @@ -37,10 +51,7 @@ branches: prevent-increment-of-merged-branch-version: true track-merge-target: false source-branches: [ 'develop', 'release' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: true - pre-release-weight: 55000 + is-main-branch: true develop: regex: ^dev(elop)?(ment)?$ @@ -53,7 +64,6 @@ branches: tracks-release-branches: true is-release-branch: false is-mainline: false - pre-release-weight: 0 release: regex: ^release?[/-] @@ -66,20 +76,15 @@ branches: tracks-release-branches: false is-release-branch: true is-mainline: false - pre-release-weight: 30000 feature: regex: ^feature?[/-] - mode: ContinuousDeployment + mode: ContinuousDelivery tag: useBranchName increment: Inherit prevent-increment-of-merged-branch-version: false - track-merge-target: false - source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false - pre-release-weight: 30000 + track-merge-target: true + source-branches: [ 'release', 'feature' ] pull-request: regex: ^(pull|pull\-requests|pr)[/-] @@ -88,12 +93,7 @@ branches: increment: Inherit prevent-increment-of-merged-branch-version: false tag-number-pattern: '[/-](?\d+)[-/]' - track-merge-target: false - source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false - pre-release-weight: 30000 + source-branches: [ 'main', 'release', 'feature', 'support', 'hotfix' ] hotfix: regex: ^hotfix(es)?[/-] From 10b94cfc063953988503586aa31bff0a8ea0f802 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 01:03:09 +0100 Subject: [PATCH 247/352] askjhadj --- .gitversion/version.yml | 80 +++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 43d878c3..40c6c51b 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -6,12 +6,14 @@ strategies: assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' assembly-informational-format: "{FullSemVer}" +semantic-version-format: Strict increment: Patch continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" +commits-since-version-source-padding: 0 build-metadata-padding: 0 legacy-semver-padding: 0 @@ -20,24 +22,9 @@ minor-version-bump-message: '\+semver:\s?(feature|minor)' patch-version-bump-message: '\+semver:\s?(fix|patch)' no-bump-message: '\+semver:\s?(none|skip)' -commits-since-version-source-padding: 4 -commit-message-incrementing: Enabled +commit-message-incrementing: Disable commit-date-format: "yyyy-MM-dd" -is-release-branch: false -is-main-branch: false -is-mainline: false - -prevent-increment: - of-merged-branch-version: true - when-branch-merged: true - when-current-commit-tagged: true - -track-merge-target: false -track-merge-message: false -tracks-release-branches: false - - ignore: sha: [] @@ -47,44 +34,61 @@ branches: regex: ^master$|^main$ mode: ContinuousDelivery tag: '' - increment: Patch - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'develop', 'release' ] - is-main-branch: true - - develop: - regex: ^dev(elop)?(ment)?$ - mode: ContinuousDeployment - tag: alpha - increment: Minor - prevent-increment-of-merged-branch-version: false - track-merge-target: true - source-branches: [] - tracks-release-branches: true + increment: Inherit + source-branches: [ 'release' ] + is-release-branch: false + is-main-branch: false is-mainline: false + track-merge-target: false + track-merge-message: false + tracks-release-branches: true + + prevent-increment: + of-merged-branch-version: false + when-branch-merged: true + when-current-commit-tagged: true + release: regex: ^release?[/-] mode: ContinuousDelivery tag: beta increment: None - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'develop', 'main', 'support', 'release' ] - tracks-release-branches: false + source-branches: [ 'main', 'release', 'preview', 'support' ] + is-release-branch: true + is-main-branch: false is-mainline: false + track-merge-target: false + track-merge-message: false + tracks-release-branches: false + + prevent-increment: + of-merged-branch-version: true + when-branch-merged: true + when-current-commit-tagged: true + feature: regex: ^feature?[/-] mode: ContinuousDelivery tag: useBranchName increment: Inherit - prevent-increment-of-merged-branch-version: false - track-merge-target: true - source-branches: [ 'release', 'feature' ] + source-branches: [ 'preview' ] + + is-release-branch: true + is-main-branch: false + is-mainline: false + + track-merge-target: false + track-merge-message: false + tracks-release-branches: false + + prevent-increment: + of-merged-branch-version: true + when-branch-merged: true + when-current-commit-tagged: true pull-request: regex: ^(pull|pull\-requests|pr)[/-] From db7fa56d1cf15172e94b93cb0ad3fae150ef4d91 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 01:05:24 +0100 Subject: [PATCH 248/352] jklhsd --- .gitversion/version.yml | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 40c6c51b..ff014d35 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -45,10 +45,9 @@ branches: track-merge-message: false tracks-release-branches: true - prevent-increment: - of-merged-branch-version: false - when-branch-merged: true - when-current-commit-tagged: true + prevent-increment-of-merged-branch-version: false + prevent-increment-when-branch-merged: true + prevent-increment-when-current-commit-tagged: true release: regex: ^release?[/-] @@ -65,10 +64,9 @@ branches: track-merge-message: false tracks-release-branches: false - prevent-increment: - of-merged-branch-version: true - when-branch-merged: true - when-current-commit-tagged: true + prevent-increment-of-merged-branch-version: true + prevent-increment-when-branch-merged: true + prevent-increment-when-current-commit-tagged: true feature: regex: ^feature?[/-] @@ -77,18 +75,17 @@ branches: increment: Inherit source-branches: [ 'preview' ] - is-release-branch: true + is-release-branch: false is-main-branch: false is-mainline: false - track-merge-target: false + track-merge-target: true track-merge-message: false tracks-release-branches: false - prevent-increment: - of-merged-branch-version: true - when-branch-merged: true - when-current-commit-tagged: true + prevent-increment-of-merged-branch-version: true + prevent-increment-when-branch-merged: true + prevent-increment-when-current-commit-tagged: true pull-request: regex: ^(pull|pull\-requests|pr)[/-] From 7a60b67f85ce1fd9989a348837f27e8ab4d6c007 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 01:06:36 +0100 Subject: [PATCH 249/352] kjhkj --- .gitversion/version.yml | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index ff014d35..b0773d1f 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -53,7 +53,7 @@ branches: regex: ^release?[/-] mode: ContinuousDelivery tag: beta - increment: None + increment: Inherit source-branches: [ 'main', 'release', 'preview', 'support' ] is-release-branch: true @@ -94,30 +94,4 @@ branches: increment: Inherit prevent-increment-of-merged-branch-version: false tag-number-pattern: '[/-](?\d+)[-/]' - source-branches: [ 'main', 'release', 'feature', 'support', 'hotfix' ] - - hotfix: - regex: ^hotfix(es)?[/-] - mode: ContinuousDelivery - tag: beta - increment: Patch - prevent-increment-of-merged-branch-version: false - track-merge-target: false - source-branches: [ 'develop', 'main', 'support' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false - pre-release-weight: 30000 - - support: - regex: ^support[/-] - mode: ContinuousDelivery - tag: '' - increment: Patch - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'main' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: true - pre-release-weight: 55000 \ No newline at end of file + source-branches: [ 'main', 'release', 'feature', 'support', 'hotfix' ] \ No newline at end of file From b480e13e69a465b4352b4acdbebc73d83d2eaa92 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 01:13:41 +0100 Subject: [PATCH 250/352] khasdiqw --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index b0773d1f..6c12e3ce 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -22,7 +22,7 @@ minor-version-bump-message: '\+semver:\s?(feature|minor)' patch-version-bump-message: '\+semver:\s?(fix|patch)' no-bump-message: '\+semver:\s?(none|skip)' -commit-message-incrementing: Disable +commit-message-incrementing: Disabled commit-date-format: "yyyy-MM-dd" ignore: From 13c00cbf8f9e5d34a872a9b201a9c2dfa9f7b903 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 01:17:16 +0100 Subject: [PATCH 251/352] jkhkuh --- .gitversion/version.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 6c12e3ce..432609cd 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,7 +1,4 @@ mode: ContinuousDeployment -strategies: -- VersionInBranchName -- TrackReleaseBranches assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' From b47d1913649e0e6b035f49815de6d220179547d4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 01:19:02 +0100 Subject: [PATCH 252/352] zsfdsf --- .gitversion/version.yml | 117 ++++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 52 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 432609cd..f555d4c6 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,89 +1,73 @@ mode: ContinuousDeployment -assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' +assembly-versioning-format: '{Major}.{Minor}.{Patch}.{CommitsSinceVersionSource}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{CommitsSinceVersionSource}' assembly-informational-format: "{FullSemVer}" -semantic-version-format: Strict increment: Patch - +next-version: 0.9.0.0 # continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" - -commits-since-version-source-padding: 0 build-metadata-padding: 0 legacy-semver-padding: 0 - major-version-bump-message: '\+semver:\s?(breaking|major)' minor-version-bump-message: '\+semver:\s?(feature|minor)' patch-version-bump-message: '\+semver:\s?(fix|patch)' no-bump-message: '\+semver:\s?(none|skip)' - -commit-message-incrementing: Disabled +commits-since-version-source-padding: 4 +commit-message-incrementing: Enabled commit-date-format: "yyyy-MM-dd" - ignore: sha: [] - branches: - main: regex: ^master$|^main$ mode: ContinuousDelivery tag: '' - increment: Inherit - source-branches: [ 'release' ] - - is-release-branch: false - is-main-branch: false - is-mainline: false - + increment: Patch + prevent-increment-of-merged-branch-version: true track-merge-target: false - track-merge-message: false - tracks-release-branches: true - + source-branches: [ 'develop', 'release' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: true + pre-release-weight: 55000 + develop: + regex: ^dev(elop)?(ment)?$ + mode: ContinuousDeployment + tag: alpha + increment: Minor prevent-increment-of-merged-branch-version: false - prevent-increment-when-branch-merged: true - prevent-increment-when-current-commit-tagged: true - + track-merge-target: true + source-branches: [] + tracks-release-branches: true + is-release-branch: false + is-mainline: false + pre-release-weight: 0 release: regex: ^release?[/-] mode: ContinuousDelivery tag: beta - increment: Inherit - source-branches: [ 'main', 'release', 'preview', 'support' ] - - is-release-branch: true - is-main-branch: false - is-mainline: false - + increment: None + prevent-increment-of-merged-branch-version: true track-merge-target: false - track-merge-message: false + source-branches: [ 'develop', 'main', 'support', 'release' ] tracks-release-branches: false - - prevent-increment-of-merged-branch-version: true - prevent-increment-when-branch-merged: true - prevent-increment-when-current-commit-tagged: true - + is-release-branch: true + is-mainline: false + pre-release-weight: 30000 feature: regex: ^feature?[/-] - mode: ContinuousDelivery + mode: ContinuousDeployment tag: useBranchName increment: Inherit - source-branches: [ 'preview' ] - + prevent-increment-of-merged-branch-version: false + track-merge-target: false + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + tracks-release-branches: false is-release-branch: false - is-main-branch: false is-mainline: false - - track-merge-target: true - track-merge-message: false - tracks-release-branches: false - - prevent-increment-of-merged-branch-version: true - prevent-increment-when-branch-merged: true - prevent-increment-when-current-commit-tagged: true - + pre-release-weight: 30000 pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery @@ -91,4 +75,33 @@ branches: increment: Inherit prevent-increment-of-merged-branch-version: false tag-number-pattern: '[/-](?\d+)[-/]' - source-branches: [ 'main', 'release', 'feature', 'support', 'hotfix' ] \ No newline at end of file + track-merge-target: false + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 + hotfix: + regex: ^hotfix(es)?[/-] + mode: ContinuousDelivery + tag: beta + increment: Patch + prevent-increment-of-merged-branch-version: false + track-merge-target: false + source-branches: [ 'develop', 'main', 'support' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 + support: + regex: ^support[/-] + mode: ContinuousDelivery + tag: '' + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'main' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: true + pre-release-weight: 55000 \ No newline at end of file From c1de599b981acc0ce285a092ce26a0f66ffc46ca Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 01:20:17 +0100 Subject: [PATCH 253/352] dshfdwe --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index f555d4c6..b124ad1d 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -15,7 +15,7 @@ minor-version-bump-message: '\+semver:\s?(feature|minor)' patch-version-bump-message: '\+semver:\s?(fix|patch)' no-bump-message: '\+semver:\s?(none|skip)' commits-since-version-source-padding: 4 -commit-message-incrementing: Enabled +commit-message-incrementing: Disabled commit-date-format: "yyyy-MM-dd" ignore: sha: [] From 5adb2f9d89d0a20f0124e83070097fe4c33f5b86 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 01:21:54 +0100 Subject: [PATCH 254/352] zdfsdrws --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index b124ad1d..7bc6664f 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,7 +1,7 @@ mode: ContinuousDeployment -assembly-versioning-format: '{Major}.{Minor}.{Patch}.{CommitsSinceVersionSource}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{CommitsSinceVersionSource}' +assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' assembly-informational-format: "{FullSemVer}" increment: Patch From db37def395fe9ae1cbb68dd92cdc4ab5341e30d4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 01:25:44 +0100 Subject: [PATCH 255/352] jyuy --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 7bc6664f..b124ad1d 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,7 +1,7 @@ mode: ContinuousDeployment -assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' +assembly-versioning-format: '{Major}.{Minor}.{Patch}.{CommitsSinceVersionSource}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{CommitsSinceVersionSource}' assembly-informational-format: "{FullSemVer}" increment: Patch From 61c1f8de183f1fdc81ceaddd55d93583e0932b41 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 01:41:53 +0100 Subject: [PATCH 256/352] asfad --- .github/workflows/dotnet.yml | 5 ++++- .gitversion/version.yml | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 32a33a47..096d9e6b 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -22,12 +22,15 @@ jobs: versionSpec: ${{ vars.GIT_VERSION }} preferLatestVersion: true - name: Update Version with GitVersion ${{ vars.GIT_VERSION }} - id: version_step uses: gittools/actions/gitversion/execute@v3.1.11 with: useConfigFile: true configFilePath: ./.gitversion/version.yml updateAssemblyInfo: false + overrideConfig: + description: | + assembly-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' + assembly-file-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' - run: 'echo FullSemVer: ${{ env.fullSemVer }}' build: diff --git a/.gitversion/version.yml b/.gitversion/version.yml index b124ad1d..3c65f613 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,7 +1,7 @@ mode: ContinuousDeployment -assembly-versioning-format: '{Major}.{Minor}.{Patch}.{CommitsSinceVersionSource}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{CommitsSinceVersionSource}' +assembly-versioning-format: '{Major}.{Minor}.{Patch}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}' assembly-informational-format: "{FullSemVer}" increment: Patch From 687b535554e00544cceb581d817cc11d7518b2e0 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 01:43:53 +0100 Subject: [PATCH 257/352] kgiu --- .github/workflows/dotnet.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 096d9e6b..a7fe98e7 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -27,10 +27,9 @@ jobs: useConfigFile: true configFilePath: ./.gitversion/version.yml updateAssemblyInfo: false - overrideConfig: - description: | - assembly-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' - assembly-file-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' + overrideConfig: | + assembly-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' + assembly-file-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' - run: 'echo FullSemVer: ${{ env.fullSemVer }}' build: From a8f3fcacdbbb7790dcb86aa9c8e1c29068e2cdb1 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 01:49:08 +0100 Subject: [PATCH 258/352] yuy --- .github/workflows/dotnet.yml | 3 --- .gitversion/version.yml | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index a7fe98e7..9a6edcae 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -27,9 +27,6 @@ jobs: useConfigFile: true configFilePath: ./.gitversion/version.yml updateAssemblyInfo: false - overrideConfig: | - assembly-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' - assembly-file-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' - run: 'echo FullSemVer: ${{ env.fullSemVer }}' build: diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 3c65f613..a9a092ea 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,7 +1,7 @@ mode: ContinuousDeployment -assembly-versioning-format: '{Major}.{Minor}.{Patch}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}' +assembly-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' assembly-informational-format: "{FullSemVer}" increment: Patch From 197ac4775ca121d1a7aa029d5f5026ae0a0228ea Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 01:50:34 +0100 Subject: [PATCH 259/352] dfsd --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 9a6edcae..cb05f4b2 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -26,7 +26,7 @@ jobs: with: useConfigFile: true configFilePath: ./.gitversion/version.yml - updateAssemblyInfo: false + updateAssemblyInfo: true - run: 'echo FullSemVer: ${{ env.fullSemVer }}' build: From e22c708fbe1bca03d52fc8decf38d3ffd2dedf0d Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 01:53:38 +0100 Subject: [PATCH 260/352] xfsdvsw --- .github/workflows/dotnet.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index cb05f4b2..5583c39b 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -6,8 +6,6 @@ on: - 'main' - 'release/**' -concurrency: ${{ github.ref }} - jobs: version: name: Version with GitVersion ${{ vars.GIT_VERSION }} From 4761b065a5451da4edec1718fa44b61ad4e86c67 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 02:03:31 +0100 Subject: [PATCH 261/352] `zsac --- .gitversion/version.yml | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index a9a092ea..2c56111e 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -5,7 +5,6 @@ assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number assembly-informational-format: "{FullSemVer}" increment: Patch -next-version: 0.9.0.0 # continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" build-metadata-padding: 0 @@ -27,23 +26,11 @@ branches: increment: Patch prevent-increment-of-merged-branch-version: true track-merge-target: false - source-branches: [ 'develop', 'release' ] + source-branches: [ 'release' ] tracks-release-branches: false is-release-branch: false is-mainline: true pre-release-weight: 55000 - develop: - regex: ^dev(elop)?(ment)?$ - mode: ContinuousDeployment - tag: alpha - increment: Minor - prevent-increment-of-merged-branch-version: false - track-merge-target: true - source-branches: [] - tracks-release-branches: true - is-release-branch: false - is-mainline: false - pre-release-weight: 0 release: regex: ^release?[/-] mode: ContinuousDelivery @@ -51,7 +38,7 @@ branches: increment: None prevent-increment-of-merged-branch-version: true track-merge-target: false - source-branches: [ 'develop', 'main', 'support', 'release' ] + source-branches: [ 'main', 'release', 'hotfix', 'support', 'bugfix' ] tracks-release-branches: false is-release-branch: true is-mainline: false @@ -61,13 +48,19 @@ branches: mode: ContinuousDeployment tag: useBranchName increment: Inherit - prevent-increment-of-merged-branch-version: false - track-merge-target: false - source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + source-branches: [ 'preview' ] + + prevent-increment-of-merged-branch: false + prevent-increment-when-branch-merged: false + prevent-increment-when-current-commit-tagged: true + + track-merge-target: true + track-merge-message: false tracks-release-branches: false + is-release-branch: false + is-main-branch: false is-mainline: false - pre-release-weight: 30000 pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery From f9908466812923ce817c8e43bd840525f1e88a42 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 02:06:13 +0100 Subject: [PATCH 262/352] kgj --- .gitversion/version.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 2c56111e..6d639c0a 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -43,6 +43,9 @@ branches: is-release-branch: true is-mainline: false pre-release-weight: 30000 + preview: + regex: ^feature?[/-] + mode: ContinuousDeployment feature: regex: ^feature?[/-] mode: ContinuousDeployment From 59d2a8c670ae48b23151a8751d33f09484bb84f7 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 02:06:23 +0100 Subject: [PATCH 263/352] kghiu --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 6d639c0a..b3d5aaf0 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -44,7 +44,7 @@ branches: is-mainline: false pre-release-weight: 30000 preview: - regex: ^feature?[/-] + regex: ^preview?[/-] mode: ContinuousDeployment feature: regex: ^feature?[/-] From 7d73c2302536da1d0b6029c21e48a72e418de369 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 02:14:53 +0100 Subject: [PATCH 264/352] ljh --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 5583c39b..39b09b07 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -24,7 +24,7 @@ jobs: with: useConfigFile: true configFilePath: ./.gitversion/version.yml - updateAssemblyInfo: true + updateAssemblyInfo: false - run: 'echo FullSemVer: ${{ env.fullSemVer }}' build: From b3fbf918b7ad08661dabd74d0fd09bcd49397e99 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 02:15:32 +0100 Subject: [PATCH 265/352] huikhi --- .github/workflows/dotnet.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 39b09b07..9d7d6a84 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -25,6 +25,9 @@ jobs: useConfigFile: true configFilePath: ./.gitversion/version.yml updateAssemblyInfo: false + overrideConfig: | + assembly-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' + assembly-file-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' - run: 'echo FullSemVer: ${{ env.fullSemVer }}' build: From 8e0867c597a1a03bad24e8eab488bd445ae9ff3f Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 11:30:25 +0100 Subject: [PATCH 266/352] kljlk --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index b3d5aaf0..81d8e338 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,7 +1,7 @@ mode: ContinuousDeployment -assembly-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' +assembly-versioning-format: '{Major}.{Minor}.{Patch}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}' assembly-informational-format: "{FullSemVer}" increment: Patch From 022b136104fba6bb5bfa3a3865c9893f46a2e635 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 11:31:33 +0100 Subject: [PATCH 267/352] uhiuhu --- .github/workflows/dotnet.yml | 3 --- .gitversion/version.yml | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 9d7d6a84..39b09b07 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -25,9 +25,6 @@ jobs: useConfigFile: true configFilePath: ./.gitversion/version.yml updateAssemblyInfo: false - overrideConfig: | - assembly-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' - assembly-file-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' - run: 'echo FullSemVer: ${{ env.fullSemVer }}' build: diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 81d8e338..b3d5aaf0 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,7 +1,7 @@ mode: ContinuousDeployment -assembly-versioning-format: '{Major}.{Minor}.{Patch}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}' +assembly-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' assembly-informational-format: "{FullSemVer}" increment: Patch From ecbe7a39f4b9659d86f5a6b5dd49aa4795395185 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 11:36:35 +0100 Subject: [PATCH 268/352] dfsdv --- .gitversion/version.yml | 59 ++++------------------------------------- 1 file changed, 5 insertions(+), 54 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index b3d5aaf0..e9e8ba21 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -23,81 +23,32 @@ branches: regex: ^master$|^main$ mode: ContinuousDelivery tag: '' - increment: Patch - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'release' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: true + increment: Inherit pre-release-weight: 55000 release: regex: ^release?[/-] mode: ContinuousDelivery tag: beta - increment: None - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'main', 'release', 'hotfix', 'support', 'bugfix' ] - tracks-release-branches: false - is-release-branch: true - is-mainline: false - pre-release-weight: 30000 - preview: - regex: ^preview?[/-] - mode: ContinuousDeployment + increment: Inherit + feature: regex: ^feature?[/-] mode: ContinuousDeployment tag: useBranchName increment: Inherit - source-branches: [ 'preview' ] - - prevent-increment-of-merged-branch: false - prevent-increment-when-branch-merged: false - prevent-increment-when-current-commit-tagged: true - - track-merge-target: true - track-merge-message: false - tracks-release-branches: false - - is-release-branch: false - is-main-branch: false - is-mainline: false pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery tag: pr- increment: Inherit - prevent-increment-of-merged-branch-version: false tag-number-pattern: '[/-](?\d+)[-/]' - track-merge-target: false - source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false - pre-release-weight: 30000 hotfix: regex: ^hotfix(es)?[/-] mode: ContinuousDelivery tag: beta - increment: Patch - prevent-increment-of-merged-branch-version: false - track-merge-target: false - source-branches: [ 'develop', 'main', 'support' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false - pre-release-weight: 30000 + increment: Inherit support: regex: ^support[/-] mode: ContinuousDelivery tag: '' - increment: Patch - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'main' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: true - pre-release-weight: 55000 \ No newline at end of file + increment: Inherit From 559b73adfaad8a6bee97416b2a908ecdae70b2d7 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 11:41:02 +0100 Subject: [PATCH 269/352] dvsfv --- .github/workflows/dotnet.yml | 8 ++++- .gitversion/version.yml | 67 ++++++++++++++++++++++++++++++++---- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 39b09b07..34bfd3f8 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -6,6 +6,8 @@ on: - 'main' - 'release/**' +concurrency: ${{ github.ref }} + jobs: version: name: Version with GitVersion ${{ vars.GIT_VERSION }} @@ -25,6 +27,10 @@ jobs: useConfigFile: true configFilePath: ./.gitversion/version.yml updateAssemblyInfo: false + overrideConfig: + description: | + assembly-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' + assembly-file-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' - run: 'echo FullSemVer: ${{ env.fullSemVer }}' build: @@ -87,4 +93,4 @@ jobs: with: name: package path: | - **/*.nupkg + **/*.nupkg \ No newline at end of file diff --git a/.gitversion/version.yml b/.gitversion/version.yml index e9e8ba21..3c65f613 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,10 +1,11 @@ mode: ContinuousDeployment -assembly-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' +assembly-versioning-format: '{Major}.{Minor}.{Patch}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}' assembly-informational-format: "{FullSemVer}" increment: Patch +next-version: 0.9.0.0 # continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" build-metadata-padding: 0 @@ -23,32 +24,84 @@ branches: regex: ^master$|^main$ mode: ContinuousDelivery tag: '' - increment: Inherit + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'develop', 'release' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: true pre-release-weight: 55000 + develop: + regex: ^dev(elop)?(ment)?$ + mode: ContinuousDeployment + tag: alpha + increment: Minor + prevent-increment-of-merged-branch-version: false + track-merge-target: true + source-branches: [] + tracks-release-branches: true + is-release-branch: false + is-mainline: false + pre-release-weight: 0 release: regex: ^release?[/-] mode: ContinuousDelivery tag: beta - increment: Inherit - + increment: None + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'develop', 'main', 'support', 'release' ] + tracks-release-branches: false + is-release-branch: true + is-mainline: false + pre-release-weight: 30000 feature: regex: ^feature?[/-] mode: ContinuousDeployment tag: useBranchName increment: Inherit + prevent-increment-of-merged-branch-version: false + track-merge-target: false + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery tag: pr- increment: Inherit + prevent-increment-of-merged-branch-version: false tag-number-pattern: '[/-](?\d+)[-/]' + track-merge-target: false + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 hotfix: regex: ^hotfix(es)?[/-] mode: ContinuousDelivery tag: beta - increment: Inherit + increment: Patch + prevent-increment-of-merged-branch-version: false + track-merge-target: false + source-branches: [ 'develop', 'main', 'support' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 support: regex: ^support[/-] mode: ContinuousDelivery tag: '' - increment: Inherit + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'main' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: true + pre-release-weight: 55000 \ No newline at end of file From c8867082e2d8b092749f8e83afb77a50cac50d4d Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 11:42:32 +0100 Subject: [PATCH 270/352] kshdak --- .github/workflows/dotnet.yml | 4 ---- .gitversion/version.yml | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 34bfd3f8..d37c261a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -27,10 +27,6 @@ jobs: useConfigFile: true configFilePath: ./.gitversion/version.yml updateAssemblyInfo: false - overrideConfig: - description: | - assembly-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' - assembly-file-versioning-format='{Major}.{Minor}.{Patch}.${{ github.run_number }}' - run: 'echo FullSemVer: ${{ env.fullSemVer }}' build: diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 3c65f613..a9a092ea 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,7 +1,7 @@ mode: ContinuousDeployment -assembly-versioning-format: '{Major}.{Minor}.{Patch}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}' +assembly-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' assembly-informational-format: "{FullSemVer}" increment: Patch From 65c3ade23a675bae6f2d2bd6ff4dafc7b12d5e99 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 11:49:18 +0100 Subject: [PATCH 271/352] hjgjy --- .gitversion/version.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index a9a092ea..1fce4253 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,20 +1,24 @@ mode: ContinuousDeployment -assembly-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' +assembly-versioning-format: '{Major}.{Minor}.{Patch}{Tag}.${{ github.run_number }}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}{Tag}.${{ github.run_number }}' assembly-informational-format: "{FullSemVer}" increment: Patch next-version: 0.9.0.0 # continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" + +# Padding build-metadata-padding: 0 +commits-since-version-source-padding: 4 legacy-semver-padding: 0 +# Message bumping major-version-bump-message: '\+semver:\s?(breaking|major)' minor-version-bump-message: '\+semver:\s?(feature|minor)' patch-version-bump-message: '\+semver:\s?(fix|patch)' no-bump-message: '\+semver:\s?(none|skip)' -commits-since-version-source-padding: 4 + commit-message-incrementing: Disabled commit-date-format: "yyyy-MM-dd" ignore: From 30ff8f943d091cbf139deae281805e8a8f236924 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 11:51:57 +0100 Subject: [PATCH 272/352] uh --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 1fce4253..a45488d5 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,7 +1,7 @@ mode: ContinuousDeployment -assembly-versioning-format: '{Major}.{Minor}.{Patch}{Tag}.${{ github.run_number }}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}{Tag}.${{ github.run_number }}' +assembly-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' assembly-informational-format: "{FullSemVer}" increment: Patch From 07b6eb7e090b2efb5daccbe182d814aa7b21004d Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 12:04:57 +0100 Subject: [PATCH 273/352] lioi --- .github/workflows/dotnet.yml | 2 +- src/PolylineAlgorithm/AssemblyInfo.cs | 0 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 src/PolylineAlgorithm/AssemblyInfo.cs diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d37c261a..9931e574 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -26,7 +26,7 @@ jobs: with: useConfigFile: true configFilePath: ./.gitversion/version.yml - updateAssemblyInfo: false + updateAssemblyInfo: true - run: 'echo FullSemVer: ${{ env.fullSemVer }}' build: diff --git a/src/PolylineAlgorithm/AssemblyInfo.cs b/src/PolylineAlgorithm/AssemblyInfo.cs new file mode 100644 index 00000000..e69de29b From ea3272128239d9c2e6236d72c7414f5507a937dc Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 12:35:33 +0100 Subject: [PATCH 274/352] yguy --- .github/workflows/dotnet.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 9931e574..f88f45b8 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -12,6 +12,8 @@ jobs: version: name: Version with GitVersion ${{ vars.GIT_VERSION }} runs-on: ubuntu-latest + outputs: + SemVer: ${{ steps.gitversion.outputs.fullSemVer }} steps: - uses: actions/checkout@v3 with: @@ -21,18 +23,20 @@ jobs: with: versionSpec: ${{ vars.GIT_VERSION }} preferLatestVersion: true - - name: Update Version with GitVersion ${{ vars.GIT_VERSION }} + - name: Calculate version with GitVersion ${{ vars.GIT_VERSION }} + id: gitversion uses: gittools/actions/gitversion/execute@v3.1.11 with: useConfigFile: true configFilePath: ./.gitversion/version.yml - updateAssemblyInfo: true - run: 'echo FullSemVer: ${{ env.fullSemVer }}' build: name: Build with .NET ${{ vars.DOTNET_VERSION }} needs: [version] runs-on: ubuntu-latest + env: + semver: ${{ needs.version.outputs.SemVer }} steps: - uses: actions/checkout@v3 - name: Install .NET ${{ vars.DOTNET_VERSION }} @@ -40,7 +44,7 @@ jobs: with: dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Build with .NET ${{ vars.DOTNET_VERSION }} - run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} + run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} -p:Version=$env:semver -p:FileVersion=$env:semver - name: Upload Build uses: actions/upload-artifact@v4 with: From 26974046ae10f1a1e4659e60eadc81eddb9ce487 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 12:44:06 +0100 Subject: [PATCH 275/352] dsfs --- .github/workflows/dotnet.yml | 9 ++++++--- src/PolylineAlgorithm/AssemblyInfo.cs | 0 2 files changed, 6 insertions(+), 3 deletions(-) delete mode 100644 src/PolylineAlgorithm/AssemblyInfo.cs diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index f88f45b8..4e3c900d 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,7 +13,8 @@ jobs: name: Version with GitVersion ${{ vars.GIT_VERSION }} runs-on: ubuntu-latest outputs: - SemVer: ${{ steps.gitversion.outputs.fullSemVer }} + version: ${{ steps.gitversion.outputs.majorMinorPatch }} + versionSuffix: ${{ steps.gitversion.outputs.PreReleaseTag }} steps: - uses: actions/checkout@v3 with: @@ -30,13 +31,15 @@ jobs: useConfigFile: true configFilePath: ./.gitversion/version.yml - run: 'echo FullSemVer: ${{ env.fullSemVer }}' + - run: 'echo FullSemVer: ${{ env.majorMinorPatch }}' build: name: Build with .NET ${{ vars.DOTNET_VERSION }} needs: [version] runs-on: ubuntu-latest env: - semver: ${{ needs.version.outputs.SemVer }} + version: ${{ needs.version.outputs.version }} + versionSuffix: ${{ needs.version.outputs.versionSuffix }} steps: - uses: actions/checkout@v3 - name: Install .NET ${{ vars.DOTNET_VERSION }} @@ -44,7 +47,7 @@ jobs: with: dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Build with .NET ${{ vars.DOTNET_VERSION }} - run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} -p:Version=$env:semver -p:FileVersion=$env:semver + run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} -p:Version=$env:version -p:FileVersion=$env:version -p:AssemblyInformationalVersion=$env:version -p:VersionSuffix=$env:versionSuffix - name: Upload Build uses: actions/upload-artifact@v4 with: diff --git a/src/PolylineAlgorithm/AssemblyInfo.cs b/src/PolylineAlgorithm/AssemblyInfo.cs deleted file mode 100644 index e69de29b..00000000 From 176b9c4b680aa9d814cd9f67a0b8d2ffb36283c0 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 12:50:23 +0100 Subject: [PATCH 276/352] kgjh --- .github/workflows/dotnet.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 4e3c900d..c5ba3f66 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest outputs: version: ${{ steps.gitversion.outputs.majorMinorPatch }} - versionSuffix: ${{ steps.gitversion.outputs.PreReleaseTag }} + versionSuffix: ${{ steps.gitversion.outputs.preReleaseTag }} steps: - uses: actions/checkout@v3 with: @@ -30,8 +30,6 @@ jobs: with: useConfigFile: true configFilePath: ./.gitversion/version.yml - - run: 'echo FullSemVer: ${{ env.fullSemVer }}' - - run: 'echo FullSemVer: ${{ env.majorMinorPatch }}' build: name: Build with .NET ${{ vars.DOTNET_VERSION }} @@ -42,6 +40,8 @@ jobs: versionSuffix: ${{ needs.version.outputs.versionSuffix }} steps: - uses: actions/checkout@v3 + - run: 'echo version: ${{ env.version }}' + - run: 'echo versionSuffix: ${{ env.versionSuffix }}' - name: Install .NET ${{ vars.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: From e1a144203c2902e12add444c1ef68f01e57c4c36 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 12:58:20 +0100 Subject: [PATCH 277/352] kug --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c5ba3f66..545854d1 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -47,7 +47,7 @@ jobs: with: dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Build with .NET ${{ vars.DOTNET_VERSION }} - run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} -p:Version=$env:version -p:FileVersion=$env:version -p:AssemblyInformationalVersion=$env:version -p:VersionSuffix=$env:versionSuffix + run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} -p:Version=${{ env:version }} -p:FileVersion=${{ env:version }} -p:AssemblyInformationalVersion=${{ env:version }} -p:VersionSuffix=${{ env:versionSuffix }} - name: Upload Build uses: actions/upload-artifact@v4 with: From e69c87c501632012298d8db5692f6de8da2f036a Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 12:59:52 +0100 Subject: [PATCH 278/352] jguyjg --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 545854d1..d8c25fd6 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -47,7 +47,7 @@ jobs: with: dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Build with .NET ${{ vars.DOTNET_VERSION }} - run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} -p:Version=${{ env:version }} -p:FileVersion=${{ env:version }} -p:AssemblyInformationalVersion=${{ env:version }} -p:VersionSuffix=${{ env:versionSuffix }} + run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} -p:Version=${{ env.version }} -p:FileVersion=${{ env.version }} -p:AssemblyInformationalVersion=${{ env.version }} -p:VersionSuffix=${{ env.versionSuffix }} - name: Upload Build uses: actions/upload-artifact@v4 with: From 4fe20501e3d8ee3865ad12767eee8906221a6824 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 13:34:21 +0100 Subject: [PATCH 279/352] kguyj --- .github/workflows/dotnet.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d8c25fd6..f6b059dc 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,8 +13,7 @@ jobs: name: Version with GitVersion ${{ vars.GIT_VERSION }} runs-on: ubuntu-latest outputs: - version: ${{ steps.gitversion.outputs.majorMinorPatch }} - versionSuffix: ${{ steps.gitversion.outputs.preReleaseTag }} + VERSION: ${{ steps.gitversion.outputs.majorMinorPatch }}${{ PreReleaseTagWithDash }} steps: - uses: actions/checkout@v3 with: @@ -36,8 +35,7 @@ jobs: needs: [version] runs-on: ubuntu-latest env: - version: ${{ needs.version.outputs.version }} - versionSuffix: ${{ needs.version.outputs.versionSuffix }} + VERSION: ${{ needs.version.outputs.VERSION }} steps: - uses: actions/checkout@v3 - run: 'echo version: ${{ env.version }}' @@ -47,7 +45,7 @@ jobs: with: dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Build with .NET ${{ vars.DOTNET_VERSION }} - run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} -p:Version=${{ env.version }} -p:FileVersion=${{ env.version }} -p:AssemblyInformationalVersion=${{ env.version }} -p:VersionSuffix=${{ env.versionSuffix }} + run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} -p:Version=${{ env.VERSION }} -p:FileVersion=${{ env.VERSION }} -p:AssemblyInformationalVersion=${{ env.VERSION }} - name: Upload Build uses: actions/upload-artifact@v4 with: From f1f2b2e3b585c59a27bac888adc52f2d192526ce Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 13:38:12 +0100 Subject: [PATCH 280/352] uyuy --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index f6b059dc..c27ec209 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,7 +13,7 @@ jobs: name: Version with GitVersion ${{ vars.GIT_VERSION }} runs-on: ubuntu-latest outputs: - VERSION: ${{ steps.gitversion.outputs.majorMinorPatch }}${{ PreReleaseTagWithDash }} + VERSION: ${{ steps.gitversion.outputs.majorMinorPatch }}${{ steps.gitversion.outputs.preReleaseTagWithDash }} steps: - uses: actions/checkout@v3 with: From c15a4aa4720dbdea7a6491ea8e42a2030a4997e4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 13:47:44 +0100 Subject: [PATCH 281/352] skzhaksf --- .gitversion/version.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index a45488d5..4922d0e0 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,8 +1,8 @@ mode: ContinuousDeployment -assembly-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' -assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.${{ github.run_number }}' -assembly-informational-format: "{FullSemVer}" +assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}.${{ github.run_number }}' +assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}.${{ github.run_number }}' +assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}.${{ github.run_number }}' increment: Patch next-version: 0.9.0.0 # From da4d4959a126be1ae5b3daed80a15ba226af4629 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 13:50:41 +0100 Subject: [PATCH 282/352] jguguy --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 4922d0e0..6b0b4980 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,8 +1,8 @@ mode: ContinuousDeployment assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}.${{ github.run_number }}' -assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}.${{ github.run_number }}' -assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}.${{ github.run_number }}' +# assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}.${{ github.run_number }}' +# assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}.${{ github.run_number }}' increment: Patch next-version: 0.9.0.0 # From 196b26786612f5b41f94c152cb6d8cd3cc2baa6c Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 13:54:00 +0100 Subject: [PATCH 283/352] xzvzdv --- .gitversion/version.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 6b0b4980..e86cea64 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -5,7 +5,6 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}.${{ git # assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}.${{ github.run_number }}' increment: Patch -next-version: 0.9.0.0 # continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" From 8e662d49959e26bfd38c1a8d488c272ff0f6abff Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 13:58:26 +0100 Subject: [PATCH 284/352] kg --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c27ec209..9fb5e120 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,7 +13,7 @@ jobs: name: Version with GitVersion ${{ vars.GIT_VERSION }} runs-on: ubuntu-latest outputs: - VERSION: ${{ steps.gitversion.outputs.majorMinorPatch }}${{ steps.gitversion.outputs.preReleaseTagWithDash }} + ASSEMBLY_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }} steps: - uses: actions/checkout@v3 with: @@ -45,7 +45,7 @@ jobs: with: dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Build with .NET ${{ vars.DOTNET_VERSION }} - run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} -p:Version=${{ env.VERSION }} -p:FileVersion=${{ env.VERSION }} -p:AssemblyInformationalVersion=${{ env.VERSION }} + run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} -p:Version=${{ env.ASSEMBLY_VERSION }} -p:FileVersion=${{ env.ASSEMBLY_VERSION }} -p:AssemblyInformationalVersion=${{ env.ASSEMBLY_VERSION }} - name: Upload Build uses: actions/upload-artifact@v4 with: From 1139817bd3ca0bc00323722b5977f48cad9dbe92 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 14:01:55 +0100 Subject: [PATCH 285/352] iuyiu --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 9fb5e120..ba886634 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -35,7 +35,7 @@ jobs: needs: [version] runs-on: ubuntu-latest env: - VERSION: ${{ needs.version.outputs.VERSION }} + ASSEMBLY_VERSION: ${{ needs.version.outputs.ASSEMBLY_VERSION }} steps: - uses: actions/checkout@v3 - run: 'echo version: ${{ env.version }}' From 69ab1ff9fe20e3f0018f7a44e47e69d8a3b8abba Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 14:14:21 +0100 Subject: [PATCH 286/352] kjhih --- .gitversion/version.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index e86cea64..1c9d60cd 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,8 +1,8 @@ mode: ContinuousDeployment -assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}.${{ github.run_number }}' -# assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}.${{ github.run_number }}' -# assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}.${{ github.run_number }}' +assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' +assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' +assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' increment: Patch continuous-delivery-fallback-tag: ci From c116e1e62f473ff0fc40cafbb9228e9faf3eec0a Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 14:17:20 +0100 Subject: [PATCH 287/352] ljhsdas --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index ba886634..71be124b 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -35,7 +35,7 @@ jobs: needs: [version] runs-on: ubuntu-latest env: - ASSEMBLY_VERSION: ${{ needs.version.outputs.ASSEMBLY_VERSION }} + ASSEMBLY_VERSION: ${{ needs.version.outputs.assemblySemVer }} steps: - uses: actions/checkout@v3 - run: 'echo version: ${{ env.version }}' From 20686e9e020311e6703d79a6037aaa3b304920b1 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 14:18:57 +0100 Subject: [PATCH 288/352] kgg --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 71be124b..ba886634 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -35,7 +35,7 @@ jobs: needs: [version] runs-on: ubuntu-latest env: - ASSEMBLY_VERSION: ${{ needs.version.outputs.assemblySemVer }} + ASSEMBLY_VERSION: ${{ needs.version.outputs.ASSEMBLY_VERSION }} steps: - uses: actions/checkout@v3 - run: 'echo version: ${{ env.version }}' From b223f24f661ed0a0248f1bae2848d8b582b6025a Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 14:44:37 +0100 Subject: [PATCH 289/352] jgug --- .github/workflows/dotnet.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index ba886634..3779c6de 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,7 +13,10 @@ jobs: name: Version with GitVersion ${{ vars.GIT_VERSION }} runs-on: ubuntu-latest outputs: - ASSEMBLY_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }} + ASSEMBLY_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.github.run_number }} + ASSEMBLY_INFORMATIONAL_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.github.run_number }}+${{ step.gitversion.outputs.sha }} + FILE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.github.run_number }} + PACKAGE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.github.run_number }} steps: - uses: actions/checkout@v3 with: @@ -38,8 +41,10 @@ jobs: ASSEMBLY_VERSION: ${{ needs.version.outputs.ASSEMBLY_VERSION }} steps: - uses: actions/checkout@v3 - - run: 'echo version: ${{ env.version }}' - - run: 'echo versionSuffix: ${{ env.versionSuffix }}' + - run: 'echo Assembly Version: ${{ env.ASSEMBLY_VERSION }}' + - run: 'echo File Version: ${{ env.FILE_VERSION }}' + - run: 'echo Assembly Informational Version: ${{ env.ASSEMBLY_INFORMATIONAL_VERSION }}' + - run: 'echo Package Version: ${{ env.PACKAGE_VERSION }}' - name: Install .NET ${{ vars.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: From 39dfc37d17bd4d1877255538766149f1a29c50e0 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 14:46:45 +0100 Subject: [PATCH 290/352] zsfdas --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 3779c6de..1c0381dc 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest outputs: ASSEMBLY_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.github.run_number }} - ASSEMBLY_INFORMATIONAL_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.github.run_number }}+${{ step.gitversion.outputs.sha }} + ASSEMBLY_INFORMATIONAL_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.github.run_number }}+${{ steps.gitversion.outputs.sha }} FILE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.github.run_number }} PACKAGE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.github.run_number }} steps: From d4075264e1a5090f12a60ca707bdcc2d1167eb5d Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 14:49:58 +0100 Subject: [PATCH 291/352] kgyjg --- .github/workflows/dotnet.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 1c0381dc..53be5031 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -39,6 +39,9 @@ jobs: runs-on: ubuntu-latest env: ASSEMBLY_VERSION: ${{ needs.version.outputs.ASSEMBLY_VERSION }} + ASSEMBLY_INFORMATIONAL_VERSION: ${{ needs.version.outputs.ASSEMBLY_INFORMATIONAL_VERSION }} + FILE_VERSION: ${{ needs.version.outputs.FILE_VERSION }} + PACKAGE_VERSION: ${{ needs.version.outputs.PACKAGE_VERSION }} steps: - uses: actions/checkout@v3 - run: 'echo Assembly Version: ${{ env.ASSEMBLY_VERSION }}' From cf120b493b86060bb9d78679ac309cbe0f331f21 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 14:50:39 +0100 Subject: [PATCH 292/352] xdgfsgr --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 53be5031..5b53ae4a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -53,7 +53,7 @@ jobs: with: dotnet-version: ${{ vars.DOTNET_VERSION }} - name: Build with .NET ${{ vars.DOTNET_VERSION }} - run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} -p:Version=${{ env.ASSEMBLY_VERSION }} -p:FileVersion=${{ env.ASSEMBLY_VERSION }} -p:AssemblyInformationalVersion=${{ env.ASSEMBLY_VERSION }} + run: dotnet build ./src/**/*.csproj --configuration ${{ vars.BUILD_CONFIGURATION }} /p:Platform=${{ vars.BUILD_PLATFORM }} -p:Version=${{ env.ASSEMBLY_VERSION }} -p:AssemblyInformationalVersion=${{ env.ASSEMBLY_INFORMATIONAL_VERSION }} -p:FileVersion=${{ env.FILE_VERSION }} - name: Upload Build uses: actions/upload-artifact@v4 with: From adc60703d1d11b6d362f31e16ad1c64817a14a30 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 14:53:08 +0100 Subject: [PATCH 293/352] hkh --- .github/workflows/dotnet.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 5b53ae4a..9942e391 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,10 +13,10 @@ jobs: name: Version with GitVersion ${{ vars.GIT_VERSION }} runs-on: ubuntu-latest outputs: - ASSEMBLY_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.github.run_number }} - ASSEMBLY_INFORMATIONAL_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.github.run_number }}+${{ steps.gitversion.outputs.sha }} - FILE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.github.run_number }} - PACKAGE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.github.run_number }} + ASSEMBLY_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }} + ASSEMBLY_INFORMATIONAL_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }}+${{ steps.gitversion.outputs.sha }} + FILE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }} + PACKAGE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }} steps: - uses: actions/checkout@v3 with: From 7379b2711ef4cd3217081aa2f52d3305a7619099 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 14:57:59 +0100 Subject: [PATCH 294/352] ljsdoias --- .github/workflows/dotnet.yml | 2 +- .gitversion/version.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 9942e391..0a3eccad 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -16,7 +16,7 @@ jobs: ASSEMBLY_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }} ASSEMBLY_INFORMATIONAL_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }}+${{ steps.gitversion.outputs.sha }} FILE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }} - PACKAGE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }} + PACKAGE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }}${{ steps.gitversion.outputs.PreReleaseLabelWithDash }} steps: - uses: actions/checkout@v3 with: diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 1c9d60cd..65d21988 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -74,7 +74,7 @@ branches: pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery - tag: pr- + tag: pr-{BranchName}- increment: Inherit prevent-increment-of-merged-branch-version: false tag-number-pattern: '[/-](?\d+)[-/]' From 51113cbde278f636a9fe4c13a8d895b1ac1b3c5f Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:00:02 +0100 Subject: [PATCH 295/352] lk`sjdas --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 65d21988..141ef044 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -74,7 +74,7 @@ branches: pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery - tag: pr-{BranchName}- + tag: {BranchName} increment: Inherit prevent-increment-of-merged-branch-version: false tag-number-pattern: '[/-](?\d+)[-/]' From 3e902d36d82403314f9a915d5fd12a05a7537f4c Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:05:22 +0100 Subject: [PATCH 296/352] dsfe --- .github/workflows/dotnet.yml | 8 ++++---- .gitversion/version.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 0a3eccad..44dcf1ea 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,10 +13,10 @@ jobs: name: Version with GitVersion ${{ vars.GIT_VERSION }} runs-on: ubuntu-latest outputs: - ASSEMBLY_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }} - ASSEMBLY_INFORMATIONAL_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }}+${{ steps.gitversion.outputs.sha }} - FILE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }} - PACKAGE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }}${{ steps.gitversion.outputs.PreReleaseLabelWithDash }} + ASSEMBLY_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}+${{ github.run_number }} + ASSEMBLY_INFORMATIONAL_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}+${{ github.run_number }}.${{ steps.gitversion.outputs.sha }} + FILE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}+${{ github.run_number }} + PACKAGE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}+${{ github.run_number }} steps: - uses: actions/checkout@v3 with: diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 141ef044..1c9d60cd 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -74,7 +74,7 @@ branches: pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery - tag: {BranchName} + tag: pr- increment: Inherit prevent-increment-of-merged-branch-version: false tag-number-pattern: '[/-](?\d+)[-/]' From 8b2818230a1bc78623e474e421db723ceb045ded Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:13:41 +0100 Subject: [PATCH 297/352] jhgjh --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 44dcf1ea..aa944b21 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -16,7 +16,7 @@ jobs: ASSEMBLY_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}+${{ github.run_number }} ASSEMBLY_INFORMATIONAL_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}+${{ github.run_number }}.${{ steps.gitversion.outputs.sha }} FILE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}+${{ github.run_number }} - PACKAGE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}+${{ github.run_number }} + PACKAGE_VERSION: ${{ steps.gitversion.outputs.fullSemVer }}+${{ github.run_number }} steps: - uses: actions/checkout@v3 with: From 7946314bb0acdb62304bba38ed987239ca7547ef Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:15:45 +0100 Subject: [PATCH 298/352] kgsdiua --- .github/workflows/dotnet.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index aa944b21..7562c231 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -13,10 +13,10 @@ jobs: name: Version with GitVersion ${{ vars.GIT_VERSION }} runs-on: ubuntu-latest outputs: - ASSEMBLY_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}+${{ github.run_number }} - ASSEMBLY_INFORMATIONAL_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}+${{ github.run_number }}.${{ steps.gitversion.outputs.sha }} - FILE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}+${{ github.run_number }} - PACKAGE_VERSION: ${{ steps.gitversion.outputs.fullSemVer }}+${{ github.run_number }} + ASSEMBLY_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }} + ASSEMBLY_INFORMATIONAL_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }}+${{ steps.gitversion.outputs.sha }} + FILE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }} + PACKAGE_VERSION: ${{ steps.gitversion.outputs.fullSemVer }}.${{ github.run_number }} steps: - uses: actions/checkout@v3 with: From afb32dd53a091a84b5eabb1b1d7d135d1814cc03 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:19:48 +0100 Subject: [PATCH 299/352] sfadw --- .gitversion/version.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 1c9d60cd..4cffa8d3 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -4,7 +4,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' -increment: Patch +increment: None continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" @@ -54,7 +54,7 @@ branches: increment: None prevent-increment-of-merged-branch-version: true track-merge-target: false - source-branches: [ 'develop', 'main', 'support', 'release' ] + source-branches: [ 'develop', 'main', 'support', 'release', 'pull-request' ] tracks-release-branches: false is-release-branch: true is-mainline: false @@ -76,14 +76,14 @@ branches: mode: ContinuousDelivery tag: pr- increment: Inherit - prevent-increment-of-merged-branch-version: false tag-number-pattern: '[/-](?\d+)[-/]' - track-merge-target: false source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + prevent-increment-of-merged-branch-version: false tracks-release-branches: false + track-merge-target: true is-release-branch: false + is-main-branch: false is-mainline: false - pre-release-weight: 30000 hotfix: regex: ^hotfix(es)?[/-] mode: ContinuousDelivery From ae12cd27b3469e3255ffdc06da89c399d8d93a44 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:21:09 +0100 Subject: [PATCH 300/352] jgj --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 4cffa8d3..875eebed 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -4,7 +4,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' -increment: None +increment: Patch continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" From b91075b279daa293d4d1cd66b9bffd3975e77b7f Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:25:03 +0100 Subject: [PATCH 301/352] xzcda --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 875eebed..e068c485 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -54,7 +54,7 @@ branches: increment: None prevent-increment-of-merged-branch-version: true track-merge-target: false - source-branches: [ 'develop', 'main', 'support', 'release', 'pull-request' ] + source-branches: [ 'develop', 'main', 'support', 'release' ] tracks-release-branches: false is-release-branch: true is-mainline: false From 30a185cb5d5eb48ca927ff07540ece632c7e7ada Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:26:05 +0100 Subject: [PATCH 302/352] Revert "xzcda" This reverts commit b91075b279daa293d4d1cd66b9bffd3975e77b7f. --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index e068c485..875eebed 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -54,7 +54,7 @@ branches: increment: None prevent-increment-of-merged-branch-version: true track-merge-target: false - source-branches: [ 'develop', 'main', 'support', 'release' ] + source-branches: [ 'develop', 'main', 'support', 'release', 'pull-request' ] tracks-release-branches: false is-release-branch: true is-mainline: false From 8db6664a51a33ab11481b5ffd6f5f49a8d7590b3 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:26:10 +0100 Subject: [PATCH 303/352] Revert "jgj" This reverts commit ae12cd27b3469e3255ffdc06da89c399d8d93a44. --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 875eebed..4cffa8d3 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -4,7 +4,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' -increment: Patch +increment: None continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" From 392890208d11e2365dd90c3cf11e426197e43bb8 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:26:15 +0100 Subject: [PATCH 304/352] Revert "sfadw" This reverts commit afb32dd53a091a84b5eabb1b1d7d135d1814cc03. --- .gitversion/version.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 4cffa8d3..1c9d60cd 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -4,7 +4,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' -increment: None +increment: Patch continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" @@ -54,7 +54,7 @@ branches: increment: None prevent-increment-of-merged-branch-version: true track-merge-target: false - source-branches: [ 'develop', 'main', 'support', 'release', 'pull-request' ] + source-branches: [ 'develop', 'main', 'support', 'release' ] tracks-release-branches: false is-release-branch: true is-mainline: false @@ -76,14 +76,14 @@ branches: mode: ContinuousDelivery tag: pr- increment: Inherit + prevent-increment-of-merged-branch-version: false tag-number-pattern: '[/-](?\d+)[-/]' + track-merge-target: false source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] - prevent-increment-of-merged-branch-version: false tracks-release-branches: false - track-merge-target: true is-release-branch: false - is-main-branch: false is-mainline: false + pre-release-weight: 30000 hotfix: regex: ^hotfix(es)?[/-] mode: ContinuousDelivery From f9f816ea62fcd1c1e5909ce5069e89e335adaff9 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:32:21 +0100 Subject: [PATCH 305/352] xzczd --- .gitversion/version.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 1c9d60cd..c841904f 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,25 +1,25 @@ mode: ContinuousDeployment +# Formats assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' +commit-date-format: "yyyy-MM-dd" +# Incrementing increment: Patch continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" - # Padding build-metadata-padding: 0 commits-since-version-source-padding: 4 legacy-semver-padding: 0 # Message bumping +commit-message-incrementing: Disabled major-version-bump-message: '\+semver:\s?(breaking|major)' minor-version-bump-message: '\+semver:\s?(feature|minor)' patch-version-bump-message: '\+semver:\s?(fix|patch)' no-bump-message: '\+semver:\s?(none|skip)' - -commit-message-incrementing: Disabled -commit-date-format: "yyyy-MM-dd" ignore: sha: [] branches: From 0090659ea2c83726cbde75851fd046136fb10551 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:34:26 +0100 Subject: [PATCH 306/352] ighjh --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index c841904f..fb687d03 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -76,10 +76,10 @@ branches: mode: ContinuousDelivery tag: pr- increment: Inherit - prevent-increment-of-merged-branch-version: false tag-number-pattern: '[/-](?\d+)[-/]' track-merge-target: false source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + prevent-increment-of-merged-branch-version: false tracks-release-branches: false is-release-branch: false is-mainline: false From 1899a5fa1bbe0892c42233485b1c0434b9b37f30 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:38:27 +0100 Subject: [PATCH 307/352] xzvds --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index fb687d03..3eb06e0b 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -74,7 +74,7 @@ branches: pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery - tag: pr- + tag: pr-{branhcName}- increment: Inherit tag-number-pattern: '[/-](?\d+)[-/]' track-merge-target: false From 7ac7901b2c65a9f94b987646655452878491c239 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:40:16 +0100 Subject: [PATCH 308/352] zxcsad --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 3eb06e0b..9ca084be 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -74,7 +74,7 @@ branches: pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery - tag: pr-{branhcName}- + tag: '{BranchName}' increment: Inherit tag-number-pattern: '[/-](?\d+)[-/]' track-merge-target: false From 92ef97a26330fff1f500ae41501a4a9e25c20869 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:42:41 +0100 Subject: [PATCH 309/352] dsfsdv --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 9ca084be..375033c2 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -74,9 +74,9 @@ branches: pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery - tag: '{BranchName}' + tag: useBranchName increment: Inherit - tag-number-pattern: '[/-](?\d+)[-/]' + # tag-number-pattern: '[/-](?\d+)[-/]' track-merge-target: false source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] prevent-increment-of-merged-branch-version: false From 83b15e8ed4d17f69fcf69e7a7587baeeaddb8771 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:45:16 +0100 Subject: [PATCH 310/352] xzdzvs --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 375033c2..51216d96 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -74,9 +74,9 @@ branches: pull-request: regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery - tag: useBranchName + tag: pull-request- increment: Inherit - # tag-number-pattern: '[/-](?\d+)[-/]' + tag-number-pattern: '[/-](?\d+)[-/]' track-merge-target: false source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] prevent-increment-of-merged-branch-version: false From c0ae29c4e7c2479a60d925e0c7e5b6e3b7e93ab4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:48:16 +0100 Subject: [PATCH 311/352] strategies --- .gitversion/version.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 51216d96..e24ea009 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -20,6 +20,12 @@ major-version-bump-message: '\+semver:\s?(breaking|major)' minor-version-bump-message: '\+semver:\s?(feature|minor)' patch-version-bump-message: '\+semver:\s?(fix|patch)' no-bump-message: '\+semver:\s?(none|skip)' + +# Strategies +strategies: +- VersionInBranchName +- Fallback + ignore: sha: [] branches: From 992677c6433786ca74abaabdca475a335d88292d Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:52:28 +0100 Subject: [PATCH 312/352] cxvxz --- .gitversion/version.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index e24ea009..c3a5fc07 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -21,11 +21,6 @@ minor-version-bump-message: '\+semver:\s?(feature|minor)' patch-version-bump-message: '\+semver:\s?(fix|patch)' no-bump-message: '\+semver:\s?(none|skip)' -# Strategies -strategies: -- VersionInBranchName -- Fallback - ignore: sha: [] branches: From b13e0ce748bc45ffea65dd0e2e20b8922ee983c4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:52:47 +0100 Subject: [PATCH 313/352] asfdswr --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index c3a5fc07..b31ce974 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -14,7 +14,7 @@ tag-prefix: "[vV]" build-metadata-padding: 0 commits-since-version-source-padding: 4 legacy-semver-padding: 0 -# Message bumping +# Automatic bumping commit-message-incrementing: Disabled major-version-bump-message: '\+semver:\s?(breaking|major)' minor-version-bump-message: '\+semver:\s?(feature|minor)' From f7045083ab073a19e2c0959351adf0f4c26f4acd Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 15:55:02 +0100 Subject: [PATCH 314/352] kjgjh --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index b31ce974..4b40f5cf 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -78,10 +78,10 @@ branches: tag: pull-request- increment: Inherit tag-number-pattern: '[/-](?\d+)[-/]' - track-merge-target: false source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] prevent-increment-of-merged-branch-version: false tracks-release-branches: false + track-merge-target: false is-release-branch: false is-mainline: false pre-release-weight: 30000 From 361b498fec2989454414e661ed3100ccc95f07d1 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 16:00:17 +0100 Subject: [PATCH 315/352] asfd --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 4b40f5cf..2c337d23 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -81,7 +81,7 @@ branches: source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] prevent-increment-of-merged-branch-version: false tracks-release-branches: false - track-merge-target: false + track-merge-target: true is-release-branch: false is-mainline: false pre-release-weight: 30000 From b5125db9cbcb544fde202639ce5da1e8e9623076 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 16:02:42 +0100 Subject: [PATCH 316/352] lzhjsd --- .gitversion/version.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 2c337d23..db87f5fa 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -10,10 +10,12 @@ commit-date-format: "yyyy-MM-dd" increment: Patch continuous-delivery-fallback-tag: ci tag-prefix: "[vV]" + # Padding build-metadata-padding: 0 commits-since-version-source-padding: 4 legacy-semver-padding: 0 + # Automatic bumping commit-message-incrementing: Disabled major-version-bump-message: '\+semver:\s?(breaking|major)' @@ -21,6 +23,9 @@ minor-version-bump-message: '\+semver:\s?(feature|minor)' patch-version-bump-message: '\+semver:\s?(fix|patch)' no-bump-message: '\+semver:\s?(none|skip)' +# Patterns +version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* + ignore: sha: [] branches: From 4aa0331c254619b2e67f07558b80a47f557d2ff5 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 16:08:22 +0100 Subject: [PATCH 317/352] cxgsd --- .gitversion/version.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index db87f5fa..1bc7321e 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -23,9 +23,6 @@ minor-version-bump-message: '\+semver:\s?(feature|minor)' patch-version-bump-message: '\+semver:\s?(fix|patch)' no-bump-message: '\+semver:\s?(none|skip)' -# Patterns -version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* - ignore: sha: [] branches: From 8c1c2e81caf4c8ed88fa11f890d63d1892a3a82d Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 16:13:07 +0100 Subject: [PATCH 318/352] soi`jdsia --- .gitversion/version (3).yml | 113 ++++++++++++++++++ .gitversion/version.yml | 228 ++++++++++++++++++++++-------------- 2 files changed, 254 insertions(+), 87 deletions(-) create mode 100644 .gitversion/version (3).yml diff --git a/.gitversion/version (3).yml b/.gitversion/version (3).yml new file mode 100644 index 00000000..1bc7321e --- /dev/null +++ b/.gitversion/version (3).yml @@ -0,0 +1,113 @@ +mode: ContinuousDeployment + +# Formats +assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' +assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' +assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' +commit-date-format: "yyyy-MM-dd" + +# Incrementing +increment: Patch +continuous-delivery-fallback-tag: ci +tag-prefix: "[vV]" + +# Padding +build-metadata-padding: 0 +commits-since-version-source-padding: 4 +legacy-semver-padding: 0 + +# Automatic bumping +commit-message-incrementing: Disabled +major-version-bump-message: '\+semver:\s?(breaking|major)' +minor-version-bump-message: '\+semver:\s?(feature|minor)' +patch-version-bump-message: '\+semver:\s?(fix|patch)' +no-bump-message: '\+semver:\s?(none|skip)' + +ignore: + sha: [] +branches: + main: + regex: ^master$|^main$ + mode: ContinuousDelivery + tag: '' + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'develop', 'release' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: true + pre-release-weight: 55000 + develop: + regex: ^dev(elop)?(ment)?$ + mode: ContinuousDeployment + tag: alpha + increment: Minor + prevent-increment-of-merged-branch-version: false + track-merge-target: true + source-branches: [] + tracks-release-branches: true + is-release-branch: false + is-mainline: false + pre-release-weight: 0 + release: + regex: ^release?[/-] + mode: ContinuousDelivery + tag: beta + increment: None + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'develop', 'main', 'support', 'release' ] + tracks-release-branches: false + is-release-branch: true + is-mainline: false + pre-release-weight: 30000 + feature: + regex: ^feature?[/-] + mode: ContinuousDeployment + tag: useBranchName + increment: Inherit + prevent-increment-of-merged-branch-version: false + track-merge-target: false + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 + pull-request: + regex: ^(pull|pull\-requests|pr)[/-] + mode: ContinuousDelivery + tag: pull-request- + increment: Inherit + tag-number-pattern: '[/-](?\d+)[-/]' + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + prevent-increment-of-merged-branch-version: false + tracks-release-branches: false + track-merge-target: true + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 + hotfix: + regex: ^hotfix(es)?[/-] + mode: ContinuousDelivery + tag: beta + increment: Patch + prevent-increment-of-merged-branch-version: false + track-merge-target: false + source-branches: [ 'develop', 'main', 'support' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: false + pre-release-weight: 30000 + support: + regex: ^support[/-] + mode: ContinuousDelivery + tag: '' + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'main' ] + tracks-release-branches: false + is-release-branch: false + is-mainline: true + pre-release-weight: 55000 \ No newline at end of file diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 1bc7321e..0de51f1c 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,113 +1,167 @@ -mode: ContinuousDeployment - -# Formats -assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' -assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' -assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' -commit-date-format: "yyyy-MM-dd" - -# Incrementing -increment: Patch -continuous-delivery-fallback-tag: ci -tag-prefix: "[vV]" - -# Padding -build-metadata-padding: 0 -commits-since-version-source-padding: 4 -legacy-semver-padding: 0 - -# Automatic bumping -commit-message-incrementing: Disabled -major-version-bump-message: '\+semver:\s?(breaking|major)' -minor-version-bump-message: '\+semver:\s?(feature|minor)' -patch-version-bump-message: '\+semver:\s?(fix|patch)' -no-bump-message: '\+semver:\s?(none|skip)' - -ignore: - sha: [] +assembly-versioning-scheme: MajorMinorPatch +assembly-file-versioning-scheme: MajorMinorPatch +tag-prefix: '[vV]?' +version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* +major-version-bump-message: \+semver:\s?(breaking|major) +minor-version-bump-message: \+semver:\s?(feature|minor) +patch-version-bump-message: \+semver:\s?(fix|patch) +no-bump-message: \+semver:\s?(none|skip) +tag-pre-release-weight: 60000 +commit-date-format: yyyy-MM-dd +merge-message-formats: {} +update-build-number: true +semantic-version-format: Strict +strategies: +- Fallback +- ConfiguredNextVersion +- MergeMessage +- TaggedCommit +- TrackReleaseBranches +- VersionInBranchName branches: - main: - regex: ^master$|^main$ - mode: ContinuousDelivery - tag: '' - increment: Patch - prevent-increment-of-merged-branch-version: true - track-merge-target: false - source-branches: [ 'develop', 'release' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: true - pre-release-weight: 55000 develop: - regex: ^dev(elop)?(ment)?$ - mode: ContinuousDeployment - tag: alpha + mode: ContinuousDelivery + label: alpha increment: Minor - prevent-increment-of-merged-branch-version: false + prevent-increment: + when-current-commit-tagged: false track-merge-target: true - source-branches: [] + track-merge-message: true + regex: ^dev(elop)?(ment)?$ + source-branches: + - main + is-source-branch-for: [] tracks-release-branches: true is-release-branch: false - is-mainline: false + is-main-branch: false pre-release-weight: 0 + main: + label: '' + increment: Patch + prevent-increment: + of-merged-branch: true + track-merge-target: false + track-merge-message: true + regex: ^master$|^main$ + source-branches: [] + is-source-branch-for: [] + tracks-release-branches: false + is-release-branch: false + is-main-branch: true + pre-release-weight: 55000 release: - regex: ^release?[/-] - mode: ContinuousDelivery - tag: beta - increment: None - prevent-increment-of-merged-branch-version: true + mode: ManualDeployment + label: beta + increment: Minor + prevent-increment: + of-merged-branch: true + when-current-commit-tagged: false track-merge-target: false - source-branches: [ 'develop', 'main', 'support', 'release' ] + regex: ^releases?[/-](?.+) + source-branches: + - main + - support + is-source-branch-for: [] tracks-release-branches: false is-release-branch: true - is-mainline: false + is-main-branch: false pre-release-weight: 30000 feature: - regex: ^feature?[/-] - mode: ContinuousDeployment - tag: useBranchName + mode: ManualDeployment + label: '{BranchName}' increment: Inherit - prevent-increment-of-merged-branch-version: false - track-merge-target: false - source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false + prevent-increment: + when-current-commit-tagged: false + track-merge-message: true + regex: ^features?[/-](?.+) + source-branches: + - develop + - main + - release + - support + - hotfix + is-source-branch-for: [] + is-main-branch: false pre-release-weight: 30000 pull-request: - regex: ^(pull|pull\-requests|pr)[/-] mode: ContinuousDelivery - tag: pull-request- + label: PullRequest increment: Inherit - tag-number-pattern: '[/-](?\d+)[-/]' - source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] - prevent-increment-of-merged-branch-version: false - tracks-release-branches: false - track-merge-target: true - is-release-branch: false - is-mainline: false + prevent-increment: + of-merged-branch: true + when-current-commit-tagged: false + label-number-pattern: '[/-](?\d+)' + track-merge-message: true + regex: ^(pull|pull\-requests|pr)[/-] + source-branches: + - develop + - main + - release + - feature + - support + - hotfix + is-source-branch-for: [] pre-release-weight: 30000 hotfix: - regex: ^hotfix(es)?[/-] - mode: ContinuousDelivery - tag: beta - increment: Patch - prevent-increment-of-merged-branch-version: false - track-merge-target: false - source-branches: [ 'develop', 'main', 'support' ] - tracks-release-branches: false - is-release-branch: false - is-mainline: false + mode: ManualDeployment + label: beta + increment: Inherit + prevent-increment: + when-current-commit-tagged: false + regex: ^hotfix(es)?[/-](?.+) + source-branches: + - main + - support + is-source-branch-for: [] + is-release-branch: true + is-main-branch: false pre-release-weight: 30000 support: - regex: ^support[/-] - mode: ContinuousDelivery - tag: '' + label: '' increment: Patch - prevent-increment-of-merged-branch-version: true + prevent-increment: + of-merged-branch: true track-merge-target: false - source-branches: [ 'main' ] + regex: ^support[/-](?.+) + source-branches: + - main + is-source-branch-for: [] tracks-release-branches: false is-release-branch: false - is-mainline: true - pre-release-weight: 55000 \ No newline at end of file + is-main-branch: true + pre-release-weight: 55000 + unknown: + mode: ManualDeployment + label: '{BranchName}' + increment: Inherit + prevent-increment: + when-current-commit-tagged: true + regex: (?.+) + source-branches: + - main + - develop + - release + - feature + - pull-request + - hotfix + - support + is-source-branch-for: [] + is-main-branch: false +ignore: + sha: [] +mode: ContinuousDelivery +label: '{BranchName}' +increment: Inherit +prevent-increment: + of-merged-branch: false + when-branch-merged: false + when-current-commit-tagged: true +track-merge-target: false +track-merge-message: true +commit-message-incrementing: Enabled +regex: '' +source-branches: [] +is-source-branch-for: [] +tracks-release-branches: false +is-release-branch: false +is-main-branch: false \ No newline at end of file From e726e46f2659d96576d3517aa703563b888c8530 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 16:15:18 +0100 Subject: [PATCH 319/352] xzxzc --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 0de51f1c..bcd4116a 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,5 +1,5 @@ -assembly-versioning-scheme: MajorMinorPatch -assembly-file-versioning-scheme: MajorMinorPatch +assembly-versioning-scheme: MajorMinor +assembly-file-versioning-scheme: MajorMinor tag-prefix: '[vV]?' version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* major-version-bump-message: \+semver:\s?(breaking|major) From c0a49f5d9c0d3d9c898687258d92ac55d53fca97 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 16:19:01 +0100 Subject: [PATCH 320/352] szfsd --- .gitversion/version.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index bcd4116a..6994d18a 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,5 +1,6 @@ -assembly-versioning-scheme: MajorMinor -assembly-file-versioning-scheme: MajorMinor +assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' +assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' +assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' tag-prefix: '[vV]?' version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* major-version-bump-message: \+semver:\s?(breaking|major) @@ -92,6 +93,7 @@ branches: when-current-commit-tagged: false label-number-pattern: '[/-](?\d+)' track-merge-message: true + track-merge-target: true regex: ^(pull|pull\-requests|pr)[/-] source-branches: - develop From 9a892fef502214a689641e6453d3ee09efeae9f2 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 16:26:52 +0100 Subject: [PATCH 321/352] xzvsd --- .gitversion/version.yml | 42 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 6994d18a..19d36995 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -19,6 +19,24 @@ strategies: - TaggedCommit - TrackReleaseBranches - VersionInBranchName +ignore: + sha: [] +mode: ContinuousDelivery +label: '{BranchName}' +increment: Inherit +prevent-increment: + of-merged-branch: true + when-branch-merged: true + when-current-commit-tagged: true +track-merge-target: false +track-merge-message: false +commit-message-incrementing: Disabled +regex: '' +source-branches: [] +is-source-branch-for: [] +tracks-release-branches: false +is-release-branch: false +is-main-branch: false branches: develop: mode: ContinuousDelivery @@ -92,7 +110,7 @@ branches: of-merged-branch: true when-current-commit-tagged: false label-number-pattern: '[/-](?\d+)' - track-merge-message: true + track-merge-message: false track-merge-target: true regex: ^(pull|pull\-requests|pr)[/-] source-branches: @@ -102,8 +120,6 @@ branches: - feature - support - hotfix - is-source-branch-for: [] - pre-release-weight: 30000 hotfix: mode: ManualDeployment label: beta @@ -148,22 +164,4 @@ branches: - hotfix - support is-source-branch-for: [] - is-main-branch: false -ignore: - sha: [] -mode: ContinuousDelivery -label: '{BranchName}' -increment: Inherit -prevent-increment: - of-merged-branch: false - when-branch-merged: false - when-current-commit-tagged: true -track-merge-target: false -track-merge-message: true -commit-message-incrementing: Enabled -regex: '' -source-branches: [] -is-source-branch-for: [] -tracks-release-branches: false -is-release-branch: false -is-main-branch: false \ No newline at end of file + is-main-branch: false \ No newline at end of file From 6a3495bdd11e67d7e9fc3fbfe11a8f4aeb3bdad9 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 16:28:22 +0100 Subject: [PATCH 322/352] zxcadvc --- .gitversion/version.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 19d36995..5d94c481 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -81,10 +81,7 @@ branches: - main - support is-source-branch-for: [] - tracks-release-branches: false is-release-branch: true - is-main-branch: false - pre-release-weight: 30000 feature: mode: ManualDeployment label: '{BranchName}' From 1c6513bda85ca66478609a23da3cedb21b642cbf Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 16:30:42 +0100 Subject: [PATCH 323/352] hgjy --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 7562c231..88e15a29 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -16,7 +16,7 @@ jobs: ASSEMBLY_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }} ASSEMBLY_INFORMATIONAL_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }}+${{ steps.gitversion.outputs.sha }} FILE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}.${{ github.run_number }} - PACKAGE_VERSION: ${{ steps.gitversion.outputs.fullSemVer }}.${{ github.run_number }} + PACKAGE_VERSION: ${{ steps.gitversion.outputs.assemblySemVer }}${{ steps.gitversion.outputs.preReleaseLabelWithDash }}.${{ github.run_number }} steps: - uses: actions/checkout@v3 with: From a337ef219b72f0cdafd2126530b94268c093a09d Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 16:35:50 +0100 Subject: [PATCH 324/352] hdiausd --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 5d94c481..e035fde1 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -101,12 +101,12 @@ branches: pre-release-weight: 30000 pull-request: mode: ContinuousDelivery - label: PullRequest + # label: PullRequest increment: Inherit prevent-increment: of-merged-branch: true when-current-commit-tagged: false - label-number-pattern: '[/-](?\d+)' + # label-number-pattern: '[/-](?\d+)' track-merge-message: false track-merge-target: true regex: ^(pull|pull\-requests|pr)[/-] From 8586e5ba3b6e45cfbc905a41202c01fb9b61d2c6 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 16:40:42 +0100 Subject: [PATCH 325/352] xvsfds --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index e035fde1..4ca925d3 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -10,7 +10,7 @@ no-bump-message: \+semver:\s?(none|skip) tag-pre-release-weight: 60000 commit-date-format: yyyy-MM-dd merge-message-formats: {} -update-build-number: true +update-build-number: false semantic-version-format: Strict strategies: - Fallback From 5e183bb8fa9b73216f2d38d6a081268bd933f25f Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 16:45:11 +0100 Subject: [PATCH 326/352] kashida --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 4ca925d3..d548fe48 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -2,7 +2,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' tag-prefix: '[vV]?' -version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* +version-in-branch-pattern: (?[vV]?\d+(\.\d+)?).* major-version-bump-message: \+semver:\s?(breaking|major) minor-version-bump-message: \+semver:\s?(feature|minor) patch-version-bump-message: \+semver:\s?(fix|patch) From ad4cb5615f642e46963809a95b779dc82627e8f4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 17:11:52 +0100 Subject: [PATCH 327/352] xzfad --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index d548fe48..08902c2a 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -2,7 +2,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' tag-prefix: '[vV]?' -version-in-branch-pattern: (?[vV]?\d+(\.\d+)?).* +version-in-branch-pattern: \/(?(\d+\.\d+))(\Z|\/.*)$ major-version-bump-message: \+semver:\s?(breaking|major) minor-version-bump-message: \+semver:\s?(feature|minor) patch-version-bump-message: \+semver:\s?(fix|patch) @@ -23,7 +23,7 @@ ignore: sha: [] mode: ContinuousDelivery label: '{BranchName}' -increment: Inherit +increment: None prevent-increment: of-merged-branch: true when-branch-merged: true From 2004e45836691cf451ccf4978fb7084a21efbdd4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 17:22:53 +0100 Subject: [PATCH 328/352] kgihk --- .gitversion/version.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 08902c2a..1e936adc 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -13,12 +13,8 @@ merge-message-formats: {} update-build-number: false semantic-version-format: Strict strategies: -- Fallback -- ConfiguredNextVersion -- MergeMessage -- TaggedCommit -- TrackReleaseBranches - VersionInBranchName +- Fallback ignore: sha: [] mode: ContinuousDelivery From 67176a1156beea6c51b06a2180faf7c621ddebc0 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 17:23:48 +0100 Subject: [PATCH 329/352] xcvsf --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 1e936adc..26d1a4c6 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -17,8 +17,8 @@ strategies: - Fallback ignore: sha: [] -mode: ContinuousDelivery -label: '{BranchName}' +mode: ContinuousDeployment +label: '' increment: None prevent-increment: of-merged-branch: true From 0753366d7b085e660aa8d05ab4c6044858d77035 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 17:28:06 +0100 Subject: [PATCH 330/352] kashdas --- .github/workflows/dotnet.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 88e15a29..2884d59a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -5,6 +5,8 @@ on: branches: - 'main' - 'release/**' + workflow_dispatch: + - 'release/**' concurrency: ${{ github.ref }} From a08699d9b61cf63ee1b5894dfec391fb2aeb07bd Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 17:32:30 +0100 Subject: [PATCH 331/352] sdfsd --- .github/workflows/dotnet.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 2884d59a..31b0e622 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -6,7 +6,6 @@ on: - 'main' - 'release/**' workflow_dispatch: - - 'release/**' concurrency: ${{ github.ref }} From da5cf10f1f6104804d577e3cc272792d7cfdd379 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 17:38:53 +0100 Subject: [PATCH 332/352] dsfs --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 26d1a4c6..3d2c8ccb 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,7 +1,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' -tag-prefix: '[vV]?' +tag-prefix: '' version-in-branch-pattern: \/(?(\d+\.\d+))(\Z|\/.*)$ major-version-bump-message: \+semver:\s?(breaking|major) minor-version-bump-message: \+semver:\s?(feature|minor) From e9bc8d96b57efa633fbf95d394173f43303355a3 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 17:46:58 +0100 Subject: [PATCH 333/352] zxvd --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 3d2c8ccb..26d1a4c6 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -1,7 +1,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' -tag-prefix: '' +tag-prefix: '[vV]?' version-in-branch-pattern: \/(?(\d+\.\d+))(\Z|\/.*)$ major-version-bump-message: \+semver:\s?(breaking|major) minor-version-bump-message: \+semver:\s?(feature|minor) From 575687fcfda1c8dfd47a16523186bd09a6bf376e Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 17:47:05 +0100 Subject: [PATCH 334/352] zxvdsf --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 26d1a4c6..20bc5beb 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -2,7 +2,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' tag-prefix: '[vV]?' -version-in-branch-pattern: \/(?(\d+\.\d+))(\Z|\/.*)$ +version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* major-version-bump-message: \+semver:\s?(breaking|major) minor-version-bump-message: \+semver:\s?(feature|minor) patch-version-bump-message: \+semver:\s?(fix|patch) From 4c7726f92be602c265eca33bade3fd5e2c8d0921 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 17:54:42 +0100 Subject: [PATCH 335/352] zxczds --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 20bc5beb..55b236cd 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -2,7 +2,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' tag-prefix: '[vV]?' -version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* +version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)*).* major-version-bump-message: \+semver:\s?(breaking|major) minor-version-bump-message: \+semver:\s?(feature|minor) patch-version-bump-message: \+semver:\s?(fix|patch) From 92904db279868d0a090e6fd957c78651c2754a8c Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 18:04:09 +0100 Subject: [PATCH 336/352] xcvdffgvda --- .gitversion/version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 55b236cd..7d625eb4 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -2,7 +2,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' tag-prefix: '[vV]?' -version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)*).* +version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* major-version-bump-message: \+semver:\s?(breaking|major) minor-version-bump-message: \+semver:\s?(feature|minor) patch-version-bump-message: \+semver:\s?(fix|patch) @@ -11,7 +11,7 @@ tag-pre-release-weight: 60000 commit-date-format: yyyy-MM-dd merge-message-formats: {} update-build-number: false -semantic-version-format: Strict +semantic-version-format: Loose strategies: - VersionInBranchName - Fallback From c81f910b678061295cebe1c79c06c22fa382911f Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 18:20:56 +0100 Subject: [PATCH 337/352] zxfsd --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 7d625eb4..3bc7450d 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -2,7 +2,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' tag-prefix: '[vV]?' -version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* +version-in-branch-pattern: (?\d+(\.\d+){1}(\.\d+){0,1}) major-version-bump-message: \+semver:\s?(breaking|major) minor-version-bump-message: \+semver:\s?(feature|minor) patch-version-bump-message: \+semver:\s?(fix|patch) From c7ab59bcbcbf7471640a43f65d9b4d00041422ae Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 18:23:24 +0100 Subject: [PATCH 338/352] sfjhadsiufew --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 3bc7450d..827f4651 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -2,7 +2,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' tag-prefix: '[vV]?' -version-in-branch-pattern: (?\d+(\.\d+){1}(\.\d+){0,1}) +version-in-branch-pattern: release\/[vV]?(?\d+(\.\d+){1}(\.\d+){0,1}) major-version-bump-message: \+semver:\s?(breaking|major) minor-version-bump-message: \+semver:\s?(feature|minor) patch-version-bump-message: \+semver:\s?(fix|patch) From b9cf17d04df12363dc2576f9b479dd984e0b0450 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 18:28:54 +0100 Subject: [PATCH 339/352] xzfsd --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 827f4651..ae96d264 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -2,7 +2,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' tag-prefix: '[vV]?' -version-in-branch-pattern: release\/[vV]?(?\d+(\.\d+){1}(\.\d+){0,1}) +version-in-branch-pattern: (?[vV]?\d+(\.\d+){1}(\.\d+){0,1}) major-version-bump-message: \+semver:\s?(breaking|major) minor-version-bump-message: \+semver:\s?(feature|minor) patch-version-bump-message: \+semver:\s?(fix|patch) From 5947f237680a7f5b2e2b7f7bbcfdc270cdf6d9ce Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 18:56:54 +0100 Subject: [PATCH 340/352] xzxsd --- .gitversion/version.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index ae96d264..909e183d 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -97,11 +97,8 @@ branches: pre-release-weight: 30000 pull-request: mode: ContinuousDelivery - # label: PullRequest + label: '' increment: Inherit - prevent-increment: - of-merged-branch: true - when-current-commit-tagged: false # label-number-pattern: '[/-](?\d+)' track-merge-message: false track-merge-target: true From 5ed49f1ba3b24595a64b480332958a9321cd7a7d Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 19:22:16 +0100 Subject: [PATCH 341/352] xzzffvds --- .github/workflows/dotnet.yml | 3 +- .gitversion/version.yml | 110 ++++++++++------------------------- 2 files changed, 31 insertions(+), 82 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 31b0e622..b6bc1034 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -3,8 +3,7 @@ name: .NET on: pull_request: branches: - - 'main' - - 'release/**' + - 'release/**' workflow_dispatch: concurrency: ${{ github.ref }} diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 909e183d..04b2452e 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -34,116 +34,68 @@ tracks-release-branches: false is-release-branch: false is-main-branch: false branches: - develop: - mode: ContinuousDelivery - label: alpha - increment: Minor - prevent-increment: - when-current-commit-tagged: false - track-merge-target: true - track-merge-message: true - regex: ^dev(elop)?(ment)?$ - source-branches: - - main - is-source-branch-for: [] - tracks-release-branches: true - is-release-branch: false - is-main-branch: false - pre-release-weight: 0 main: + mode: ManualDeployment label: '' - increment: Patch - prevent-increment: - of-merged-branch: true - track-merge-target: false - track-merge-message: true + increment: Inherit regex: ^master$|^main$ - source-branches: [] - is-source-branch-for: [] - tracks-release-branches: false - is-release-branch: false is-main-branch: true - pre-release-weight: 55000 release: - mode: ManualDeployment - label: beta - increment: Minor - prevent-increment: - of-merged-branch: true - when-current-commit-tagged: false - track-merge-target: false - regex: ^releases?[/-](?.+) + mode: ContinuousDeployment + label: '' + increment: Inherit + regex: ^release(s)?[/-](?.+) source-branches: - - main + - preview + - release - support - is-source-branch-for: [] is-release-branch: true feature: - mode: ManualDeployment + mode: ContinuousDelivery label: '{BranchName}' increment: Inherit - prevent-increment: - when-current-commit-tagged: false - track-merge-message: true - regex: ^features?[/-](?.+) + regex: ^feature(s)?[/-](?.+) source-branches: - - develop - - main - - release - - support - - hotfix - is-source-branch-for: [] - is-main-branch: false - pre-release-weight: 30000 + - preview pull-request: mode: ContinuousDelivery - label: '' + label: pull-request- increment: Inherit - # label-number-pattern: '[/-](?\d+)' - track-merge-message: false track-merge-target: true regex: ^(pull|pull\-requests|pr)[/-] source-branches: - - develop - - main - - release - - feature - - support - hotfix + - bugfix + - preview + - feature + - preview hotfix: - mode: ManualDeployment - label: beta + mode: ContinuousDelivery + label: alpha increment: Inherit - prevent-increment: - when-current-commit-tagged: false regex: ^hotfix(es)?[/-](?.+) source-branches: - - main - - support - is-source-branch-for: [] - is-release-branch: true - is-main-branch: false - pre-release-weight: 30000 + - release support: - label: '' - increment: Patch + label: beta + increment: Inherit prevent-increment: of-merged-branch: true track-merge-target: false regex: ^support[/-](?.+) source-branches: - - main - is-source-branch-for: [] - tracks-release-branches: false - is-release-branch: false - is-main-branch: true - pre-release-weight: 55000 + - release + bugfix: + mode: ContinuousDelivery + label: alpha + increment: Inherit + regex: ^bugfix(es)?[/-](?.+) + source-branches: + - support unknown: mode: ManualDeployment label: '{BranchName}' increment: Inherit - prevent-increment: - when-current-commit-tagged: true regex: (?.+) source-branches: - main @@ -152,6 +104,4 @@ branches: - feature - pull-request - hotfix - - support - is-source-branch-for: [] - is-main-branch: false \ No newline at end of file + - support \ No newline at end of file From 814d26673d91b5dab460fb12e958c45fa278a76c Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 20:05:37 +0100 Subject: [PATCH 342/352] kugiu --- .gitversion/version.yml | 58 +++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 04b2452e..992279be 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -2,7 +2,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' tag-prefix: '[vV]?' -version-in-branch-pattern: (?[vV]?\d+(\.\d+){1}(\.\d+){0,1}) +version-in-branch-pattern: (?[vV]?(\d+){1}(\.\d+){1}(\.\d+){0,1}) major-version-bump-message: \+semver:\s?(breaking|major) minor-version-bump-message: \+semver:\s?(feature|minor) patch-version-bump-message: \+semver:\s?(fix|patch) @@ -40,40 +40,27 @@ branches: increment: Inherit regex: ^master$|^main$ is-main-branch: true + preview: + mode: ContinuousDeployment + label: preview + increment: Inherit + regex: ^release(s)?\/([vV]?(\d+){1}(\.\d+){1}(\.\d+){0,1})\/preview$ + source-branches: + - release release: mode: ContinuousDeployment label: '' increment: Inherit - regex: ^release(s)?[/-](?.+) + regex: ^release(s)?\/([vV]?(\d+){1}(\.\d+){1}(\.\d+){0,1})$ source-branches: - preview - - release - support is-release-branch: true - feature: - mode: ContinuousDelivery - label: '{BranchName}' - increment: Inherit - regex: ^feature(s)?[/-](?.+) - source-branches: - - preview - pull-request: - mode: ContinuousDelivery - label: pull-request- - increment: Inherit - track-merge-target: true - regex: ^(pull|pull\-requests|pr)[/-] - source-branches: - - hotfix - - bugfix - - preview - - feature - - preview hotfix: mode: ContinuousDelivery - label: alpha + label: hotfix increment: Inherit - regex: ^hotfix(es)?[/-](?.+) + regex: ^hotfix(es)?\/(?.+) source-branches: - release support: @@ -87,11 +74,30 @@ branches: - release bugfix: mode: ContinuousDelivery - label: alpha + label: bugfix increment: Inherit - regex: ^bugfix(es)?[/-](?.+) + regex: ^bugfix(es)?\/(?.+) source-branches: - support + feature: + mode: ContinuousDelivery + label: '{BranchName}' + increment: Inherit + regex: ^feature(s)?\/(?.+) + source-branches: + - preview + pull-request: + mode: ContinuousDelivery + label: pull-request- + increment: Inherit + track-merge-target: true + regex: ^(pull|pull\-requests|pr)[/-] + source-branches: + - hotfix + - bugfix + - preview + - feature + - preview unknown: mode: ManualDeployment label: '{BranchName}' From 9c12055035f2b44bdb87b017fcc8017d4e2e6dd9 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 20:10:50 +0100 Subject: [PATCH 343/352] jhgjygu --- .gitversion/version.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 992279be..4b6b491d 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -66,16 +66,15 @@ branches: support: label: beta increment: Inherit - prevent-increment: - of-merged-branch: true track-merge-target: false - regex: ^support[/-](?.+) + regex: ^support\/(?.+) source-branches: - release bugfix: mode: ContinuousDelivery label: bugfix increment: Inherit + track-merge-target: false regex: ^bugfix(es)?\/(?.+) source-branches: - support @@ -83,6 +82,7 @@ branches: mode: ContinuousDelivery label: '{BranchName}' increment: Inherit + track-merge-target: false regex: ^feature(s)?\/(?.+) source-branches: - preview From 0112cecff189bb9bda0b394b0499265c8295469e Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 20:14:36 +0100 Subject: [PATCH 344/352] xzfsvdsf --- .gitversion/version.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 4b6b491d..9b5fef3d 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -2,7 +2,7 @@ assembly-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' tag-prefix: '[vV]?' -version-in-branch-pattern: (?[vV]?(\d+){1}(\.\d+){1}(\.\d+){0,1}) +version-in-branch-pattern: (?[vV]?\d+.\d+(\.\d+){0,1}) major-version-bump-message: \+semver:\s?(breaking|major) minor-version-bump-message: \+semver:\s?(feature|minor) patch-version-bump-message: \+semver:\s?(fix|patch) @@ -44,14 +44,14 @@ branches: mode: ContinuousDeployment label: preview increment: Inherit - regex: ^release(s)?\/([vV]?(\d+){1}(\.\d+){1}(\.\d+){0,1})\/preview$ + regex: ^release(s)?\/([vV]?\d+.\d+(\.\d+){0,1})\/preview$ source-branches: - release release: mode: ContinuousDeployment label: '' increment: Inherit - regex: ^release(s)?\/([vV]?(\d+){1}(\.\d+){1}(\.\d+){0,1})$ + regex: ^release(s)?\/([vV]?\d+.\d+(\.\d+){0,1})$ source-branches: - preview - support From 3ac0bf1c485ca6e0feb4059f55390ac8a3276d78 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 20:17:52 +0100 Subject: [PATCH 345/352] xzfda --- .gitversion/version.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index 9b5fef3d..b1702538 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -93,11 +93,12 @@ branches: track-merge-target: true regex: ^(pull|pull\-requests|pr)[/-] source-branches: + - preview + - release - hotfix - bugfix - - preview + - support - feature - - preview unknown: mode: ManualDeployment label: '{BranchName}' From b4d2453eaa2791972372d23a779df26a0032d46d Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 20:34:55 +0100 Subject: [PATCH 346/352] zxfdss --- .gitversion/version.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index b1702538..a3cf27c8 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -60,13 +60,15 @@ branches: mode: ContinuousDelivery label: hotfix increment: Inherit + track-merge-target: true regex: ^hotfix(es)?\/(?.+) source-branches: - release support: + mode: ContinuousDelivery label: beta increment: Inherit - track-merge-target: false + track-merge-target: true regex: ^support\/(?.+) source-branches: - release @@ -74,7 +76,7 @@ branches: mode: ContinuousDelivery label: bugfix increment: Inherit - track-merge-target: false + track-merge-target: true regex: ^bugfix(es)?\/(?.+) source-branches: - support @@ -82,7 +84,7 @@ branches: mode: ContinuousDelivery label: '{BranchName}' increment: Inherit - track-merge-target: false + track-merge-target: true regex: ^feature(s)?\/(?.+) source-branches: - preview From c136bb2d897f409535e265fa827990a0f2b3da4d Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 20:38:47 +0100 Subject: [PATCH 347/352] safsde --- .github/workflows/dotnet.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b6bc1034..2e86a00d 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -26,6 +26,13 @@ jobs: with: versionSpec: ${{ vars.GIT_VERSION }} preferLatestVersion: true + - name: Calculate version with GitVersion ${{ vars.GIT_VERSION }} + id: gitversion + uses: gittools/actions/gitversion/command@v3.1.11 + with: + useConfigFile: true + configFilePath: ./.gitversion/version.yml + arguments: '/showConfig' - name: Calculate version with GitVersion ${{ vars.GIT_VERSION }} id: gitversion uses: gittools/actions/gitversion/execute@v3.1.11 From e8ace10cd086784aa57ac04e80477e93ad27967a Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 20:41:03 +0100 Subject: [PATCH 348/352] dzfds --- .github/workflows/dotnet.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 2e86a00d..d29334be 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -26,8 +26,7 @@ jobs: with: versionSpec: ${{ vars.GIT_VERSION }} preferLatestVersion: true - - name: Calculate version with GitVersion ${{ vars.GIT_VERSION }} - id: gitversion + - name: Show config with GitVersion ${{ vars.GIT_VERSION }} uses: gittools/actions/gitversion/command@v3.1.11 with: useConfigFile: true From 78f7c82b688b3d669c74fefa570999ee48e8e783 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 20:46:11 +0100 Subject: [PATCH 349/352] xzfdsd --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d29334be..97fcb7df 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -31,7 +31,7 @@ jobs: with: useConfigFile: true configFilePath: ./.gitversion/version.yml - arguments: '/showConfig' + arguments: '/format {Major}.{Minor}' - name: Calculate version with GitVersion ${{ vars.GIT_VERSION }} id: gitversion uses: gittools/actions/gitversion/execute@v3.1.11 From 74aa266a78acd728ee114e71e6a6221bdbc884e4 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 20:49:47 +0100 Subject: [PATCH 350/352] xgsfr --- .github/workflows/dotnet.yml | 6 ------ .gitversion/version.yml | 15 ++++----------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 97fcb7df..b6bc1034 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -26,12 +26,6 @@ jobs: with: versionSpec: ${{ vars.GIT_VERSION }} preferLatestVersion: true - - name: Show config with GitVersion ${{ vars.GIT_VERSION }} - uses: gittools/actions/gitversion/command@v3.1.11 - with: - useConfigFile: true - configFilePath: ./.gitversion/version.yml - arguments: '/format {Major}.{Minor}' - name: Calculate version with GitVersion ${{ vars.GIT_VERSION }} id: gitversion uses: gittools/actions/gitversion/execute@v3.1.11 diff --git a/.gitversion/version.yml b/.gitversion/version.yml index a3cf27c8..cda09750 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -3,13 +3,6 @@ assembly-file-versioning-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' assembly-informational-format: '{Major}.{Minor}.{CommitsSinceVersionSource}' tag-prefix: '[vV]?' version-in-branch-pattern: (?[vV]?\d+.\d+(\.\d+){0,1}) -major-version-bump-message: \+semver:\s?(breaking|major) -minor-version-bump-message: \+semver:\s?(feature|minor) -patch-version-bump-message: \+semver:\s?(fix|patch) -no-bump-message: \+semver:\s?(none|skip) -tag-pre-release-weight: 60000 -commit-date-format: yyyy-MM-dd -merge-message-formats: {} update-build-number: false semantic-version-format: Loose strategies: @@ -60,7 +53,7 @@ branches: mode: ContinuousDelivery label: hotfix increment: Inherit - track-merge-target: true + track-merge-target: false regex: ^hotfix(es)?\/(?.+) source-branches: - release @@ -68,7 +61,7 @@ branches: mode: ContinuousDelivery label: beta increment: Inherit - track-merge-target: true + track-merge-target: false regex: ^support\/(?.+) source-branches: - release @@ -76,7 +69,7 @@ branches: mode: ContinuousDelivery label: bugfix increment: Inherit - track-merge-target: true + track-merge-target: false regex: ^bugfix(es)?\/(?.+) source-branches: - support @@ -84,7 +77,7 @@ branches: mode: ContinuousDelivery label: '{BranchName}' increment: Inherit - track-merge-target: true + track-merge-target: false regex: ^feature(s)?\/(?.+) source-branches: - preview From d527104618b85127a3b72969120e17c88b1c9981 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 20:54:09 +0100 Subject: [PATCH 351/352] zxvsdv --- .gitversion/version.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index cda09750..a7a73582 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -81,6 +81,7 @@ branches: regex: ^feature(s)?\/(?.+) source-branches: - preview + - release pull-request: mode: ContinuousDelivery label: pull-request- From ecbb94d85bd4c39dc994909839a036707affead9 Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 3 Feb 2025 20:59:41 +0100 Subject: [PATCH 352/352] cvxc --- .gitversion/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitversion/version.yml b/.gitversion/version.yml index a7a73582..1ef165ab 100644 --- a/.gitversion/version.yml +++ b/.gitversion/version.yml @@ -74,7 +74,7 @@ branches: source-branches: - support feature: - mode: ContinuousDelivery + mode: ManualDeployment label: '{BranchName}' increment: Inherit track-merge-target: false