Skip to content

Commit 684d9c0

Browse files
author
Pete Sramek
committed
update
1 parent 3bebe19 commit 684d9c0

20 files changed

+65
-81
lines changed

benchmarks/PolylineAlgorithm.Benchmarks/PolylineBuilderBenchmark.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace PolylineAlgorithm.Benchmarks;
77

88
using BenchmarkDotNet.Attributes;
99
using PolylineAlgorithm;
10+
using PolylineAlgorithm.Internal;
1011
using PolylineAlgorithm.Utility;
1112

1213
/// <summary>
@@ -44,7 +45,7 @@ public class PolylineBuilderBenchmark {
4445

4546
public char[] CopyToDestination { get; private set; }
4647

47-
internal Polyline.PolylineBuilder Builder { get; private set; }
48+
internal PolylineBuilder Builder { get; private set; }
4849

4950
#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.
5051

@@ -54,7 +55,7 @@ public class PolylineBuilderBenchmark {
5455
/// </summary>
5556
[GlobalSetup]
5657
public void SetupData() {
57-
Builder = new Polyline.PolylineBuilder();
58+
Builder = new PolylineBuilder();
5859

5960
var polyline = ValueProvider.GetPolyline(Count);
6061
StringValue = polyline.ToString();

benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class PolylineDecoderBenchmark {
3232
/// <summary>
3333
/// The polyline decoder instance.
3434
/// </summary>
35-
public DefaultPolylineDecoder Decoder = new();
35+
public PolylineDecoder Decoder = new();
3636

3737
/// <summary>
3838
/// Sets up the data for the benchmarks.

benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public class PolylineEncoderBenchmark {
3434
/// <summary>
3535
/// The polyline encoder instance.
3636
/// </summary>
37-
public DefaultPolylineEncoder Encoder = new();
37+
public PolylineEncoder Encoder = new();
3838

3939
/// <summary>
4040
/// The async polyline encoder instance.

benchmarks/PolylineAlgorithm.Comparison.Benchmarks/PolylineDecoderBenchmark.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class PolylineDecoderBenchmark {
4040
/// <summary>
4141
/// The polyline decoder instance.
4242
/// </summary>
43-
public DefaultPolylineDecoder PolylineAlgorithm = new();
43+
public PolylineDecoder PolylineAlgorithm = new();
4444

4545
public PolylineEncoding Cloudikka = new();
4646

benchmarks/PolylineAlgorithm.Comparison.Benchmarks/PolylineEncoderBenchmark.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public class PolylineEncoderBenchmark {
5252
/// <summary>
5353
/// The polyline encoder instance.
5454
/// </summary>
55-
public DefaultPolylineEncoder PolylineAlgorithm = new();
55+
public PolylineEncoder PolylineAlgorithm = new();
5656

5757
public PolylineEncoding Cloudikka = new();
5858

src/PolylineAlgorithm/Abstraction/IPolylineDecoder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ namespace PolylineAlgorithm.Abstraction;
1010
/// <summary>
1111
/// Defines a method to decode an encoded polyline into a set of coordinates.
1212
/// </summary>
13-
public interface IPolylineDecoder<TCoordinate> {
13+
public interface IPolylineDecoder {
1414
/// <summary>
1515
/// Converts an encoded polyline to a set of coordinates.
1616
/// </summary>
1717
/// <param name="polyline">An encoded polyline to decode.</param>
1818
/// <returns>A set of coordinates represented by the encoded polyline.</returns>
19-
IEnumerable<TCoordinate> Decode(Polyline polyline);
19+
IEnumerable<Coordinate> Decode(Polyline polyline);
2020
}

src/PolylineAlgorithm/Abstraction/IPolylineEncoder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ namespace PolylineAlgorithm.Abstraction;
1010
/// <summary>
1111
/// Defines a method to encode a set of coordinates into an encoded polyline.
1212
/// </summary>
13-
public interface IPolylineEncoder<TCoordinate> {
13+
public interface IPolylineEncoder {
1414
/// <summary>
1515
/// Converts a set of coordinates to an encoded polyline.
1616
/// </summary>
1717
/// <param name="coordinates">A set of coordinates to encode.</param>
1818
/// <returns>An encoded polyline representing the set of coordinates.</returns>
19-
Polyline Encode(IEnumerable<TCoordinate> coordinates);
19+
Polyline Encode(IEnumerable<Coordinate> coordinates);
2020
}

src/PolylineAlgorithm/DefaultPolylineDecoder.cs

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/PolylineAlgorithm/DefaultPolylineEncoder.cs

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/PolylineAlgorithm/Extensions/PolylineDecoderExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
using System.Collections.Generic;
66

77
public static class PolylineDecoderExtensions {
8-
public static IEnumerable<TCoordinate> Decode<TCoordinate>(this IPolylineDecoder<TCoordinate> decoder, string polyline) {
8+
public static IEnumerable<Coordinate> Decode(this IPolylineDecoder decoder, string polyline) {
99
if (decoder is null) {
1010
throw new ArgumentNullException(nameof(decoder));
1111
}
1212

1313
return decoder.Decode(Polyline.FromString(polyline));
1414
}
1515

16-
public static IEnumerable<TCoordinate> Decode<TCoordinate>(this IPolylineDecoder<TCoordinate> decoder, char[] polyline) {
16+
public static IEnumerable<Coordinate> Decode(this IPolylineDecoder decoder, char[] polyline) {
1717
if (decoder is null) {
1818
throw new ArgumentNullException(nameof(decoder));
1919
}

src/PolylineAlgorithm/Extensions/PolylineEncoderExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
using System.Collections.Generic;
66

77
public static class PolylineEncoderExtensions {
8-
public static Polyline Encode<TCoordinate>(this IPolylineEncoder<TCoordinate> encoder, ICollection<TCoordinate> coordinates) {
8+
public static Polyline Encode<Coordinate>(this IPolylineEncoder encoder, ICollection<Coordinate> coordinates) {
99
if (encoder is null) {
1010
throw new ArgumentNullException(nameof(encoder));
1111
}
1212

1313
return encoder.Encode(coordinates);
1414
}
1515

16-
public static Polyline Encode<TCoordinate>(this IPolylineEncoder<TCoordinate> encoder, TCoordinate[] coordinates) {
16+
public static Polyline Encode(this IPolylineEncoder encoder, Coordinate[] coordinates) {
1717
if (encoder is null) {
1818
throw new ArgumentNullException(nameof(encoder));
1919
}

src/PolylineAlgorithm/Internal/CoordinateVariance.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
using System;
44
using System.Diagnostics;
5+
using System.Runtime.CompilerServices;
56
using System.Runtime.InteropServices;
67

78
[DebuggerDisplay($"{{{nameof(ToString)}(),nq}}")]
8-
[StructLayout(LayoutKind.Sequential, Pack = 8, Size = 16)]
9+
[StructLayout(LayoutKind.Auto)]
910
public struct CoordinateVariance {
1011
private (int Latitude, int Longitude) _current = (0, 0);
1112

@@ -18,13 +19,15 @@ private CoordinateVariance(int latitude, int longitude) {
1819

1920
public int Longitude { get; private set; }
2021

22+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2123
public void Next((int Latitude, int Longitude) next) {
2224
Latitude = Variance(_current.Latitude, next.Latitude);
2325
Longitude = Variance(_current.Longitude, next.Longitude);
2426

2527
_current = next;
2628
}
2729

30+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2831
private static int Variance(int initial, int next) => (initial, next) switch {
2932
(0, 0) => 0,
3033
(0, _) => next,
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace PolylineAlgorithm.Internal;
2+
3+
using System;
4+
using System.Runtime.InteropServices;
5+
6+
[StructLayout(LayoutKind.Auto)]
7+
internal struct PolylineBuilder {
8+
private PolylineSegment? _initial;
9+
private PolylineSegment? _last;
10+
11+
public void Append(ReadOnlyMemory<char> value) {
12+
var current = new PolylineSegment(value);
13+
14+
_initial ??= current;
15+
16+
_last?.Append(current);
17+
_last = current;
18+
}
19+
20+
public readonly Polyline Build() {
21+
if (_initial is null) {
22+
return Polyline.FromMemory(ReadOnlyMemory<char>.Empty);
23+
}
24+
25+
return Polyline.FromSequence(new(_initial, 0, _last, _last!.Memory.Length));
26+
}
27+
}

src/PolylineAlgorithm/Polyline.cs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -221,27 +221,4 @@ internal static Polyline FromSequence(ReadOnlySequence<char> value) {
221221
public static explicit operator Polyline(ReadOnlyMemory<char> polyline) => FromMemory(polyline);
222222

223223
#endregion
224-
225-
[StructLayout(LayoutKind.Auto)]
226-
internal struct PolylineBuilder {
227-
private PolylineSegment? _initial;
228-
private PolylineSegment? _last;
229-
230-
public void Append(ReadOnlyMemory<char> value) {
231-
var current = new PolylineSegment(value);
232-
233-
_initial ??= current;
234-
235-
_last?.Append(current);
236-
_last = current;
237-
}
238-
239-
public Polyline Build() {
240-
if (_initial is null) {
241-
return FromMemory(ReadOnlyMemory<char>.Empty);
242-
}
243-
244-
return FromSequence(new(_initial, 0, _last, _last!.Memory.Length));
245-
}
246-
}
247224
}

src/PolylineAlgorithm/Abstraction/PolylineDecoder.cs renamed to src/PolylineAlgorithm/PolylineDecoder.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
44
//
55

6-
namespace PolylineAlgorithm.Abstraction;
6+
namespace PolylineAlgorithm;
77

8+
using PolylineAlgorithm.Abstraction;
89
using PolylineAlgorithm.Properties;
910
using System;
1011
using System.Buffers;
@@ -14,11 +15,11 @@ namespace PolylineAlgorithm.Abstraction;
1415
/// <summary>
1516
/// Performs polyline algorithm decoding
1617
/// </summary>
17-
public abstract class PolylineDecoder<TCoordinate> : IPolylineDecoder<TCoordinate> {
18+
public class PolylineDecoder : IPolylineDecoder {
1819
/// <inheritdoc />
1920
/// <exception cref="ArgumentException">Thrown when <paramref name="polyline"/> argument is null -or- empty.</exception>
2021
/// <exception cref="InvalidOperationException">Thrown when <paramref name="polyline"/> is not in correct format.</exception>
21-
public IEnumerable<TCoordinate> Decode(Polyline polyline) {
22+
public IEnumerable<Coordinate> Decode(Polyline polyline) {
2223
if (polyline.IsEmpty) {
2324
throw new ArgumentException(ExceptionMessageResource.ArgumentCannotBeNullEmptyOrWhitespaceMessage, nameof(polyline));
2425
}
@@ -39,7 +40,7 @@ public IEnumerable<TCoordinate> Decode(Polyline polyline) {
3940
while (PolylineEncoding.Default.TryReadValue(ref latitude, ref buffer, ref position)
4041
&& PolylineEncoding.Default.TryReadValue(ref longitude, ref buffer, ref position)
4142
) {
42-
yield return Construct(PolylineEncoding.Default.Denormalize(latitude), PolylineEncoding.Default.Denormalize(longitude));
43+
yield return new(PolylineEncoding.Default.Denormalize(latitude), PolylineEncoding.Default.Denormalize(longitude));
4344
}
4445

4546
consumed += position;
@@ -49,7 +50,4 @@ public IEnumerable<TCoordinate> Decode(Polyline polyline) {
4950
}
5051
}
5152
}
52-
53-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
54-
public abstract TCoordinate Construct(double latitude, double longitude);
5553
}

src/PolylineAlgorithm/Abstraction/PolylineEncoder.cs renamed to src/PolylineAlgorithm/PolylineEncoder.cs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,19 @@
33
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
44
//
55

6-
namespace PolylineAlgorithm.Abstraction;
6+
namespace PolylineAlgorithm;
77

8+
using PolylineAlgorithm.Abstraction;
89
using PolylineAlgorithm.Internal;
910
using System;
10-
using System.Buffers;
11-
using System.Collections;
1211
using System.Collections.Generic;
1312
using System.Diagnostics.CodeAnalysis;
1413
using System.Runtime.CompilerServices;
1514

1615
/// <summary>
1716
/// Provides methods to encode a set of coordinates into a polyline string.
1817
/// </summary>\
19-
public abstract class PolylineEncoder<TCoordinate> : IPolylineEncoder<TCoordinate> {
18+
public class PolylineEncoder : IPolylineEncoder {
2019
private const int MaxByteSize = 64_000;
2120
private const int MaxChars = MaxByteSize / sizeof(char);
2221
private const int MaxCount = MaxChars / Defaults.Polyline.MaxEncodedCoordinateLength;
@@ -28,7 +27,7 @@ public abstract class PolylineEncoder<TCoordinate> : IPolylineEncoder<TCoordinat
2827
/// <returns>A <see cref="Polyline"/> representing the encoded coordinates.</returns>
2928
/// <exception cref="ArgumentNullException">Thrown when the <paramref name="coordinates"/> argument is null.</exception>
3029
/// <exception cref="ArgumentException">Thrown when the <paramref name="coordinates"/> argument is an empty enumeration.</exception>
31-
public Polyline Encode(IEnumerable<TCoordinate> coordinates) {
30+
public Polyline Encode(IEnumerable<Coordinate> coordinates) {
3231
if (coordinates is null) {
3332
throw new ArgumentNullException(nameof(coordinates));
3433
}
@@ -45,14 +44,14 @@ public Polyline Encode(IEnumerable<TCoordinate> coordinates) {
4544
int consumed = 0;
4645
int length = GetMaxLength(count);
4746
bool isMultiSegment = count == -1 || count > MaxCount;
48-
Polyline.PolylineBuilder builder = new();
47+
PolylineBuilder builder = new();
4948
Span<char> buffer = stackalloc char[length];
5049

5150
using var enumerator = coordinates.GetEnumerator();
5251

5352
while (enumerator.MoveNext()) {
5453
variance
55-
.Next(Normalize(Deconstruct(enumerator.Current)));
54+
.Next(Normalize(enumerator.Current));
5655

5756
if (isMultiSegment
5857
&& buffer.Length - position < 12) {
@@ -71,7 +70,7 @@ public Polyline Encode(IEnumerable<TCoordinate> coordinates) {
7170
consumed++;
7271

7372
[MethodImpl(MethodImplOptions.AggressiveInlining)]
74-
static (int Latitude, int Longitude) Normalize((double Latitude, double Longitude) coordinate) {
73+
static (int Latitude, int Longitude) Normalize(Coordinate coordinate) {
7574
return (PolylineEncoding.Default.Normalize(coordinate.Latitude), PolylineEncoding.Default.Normalize(coordinate.Longitude));
7675
}
7776
}
@@ -95,19 +94,16 @@ public Polyline Encode(IEnumerable<TCoordinate> coordinates) {
9594
};
9695
}
9796

98-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
99-
protected abstract (double Latitude, double Longitude) Deconstruct(TCoordinate source);
100-
10197
/// <summary>
10298
/// Gets the count of coordinates in the enumerable.
10399
/// </summary>
104100
/// <param name="coordinates">The enumerable of coordinates.</param>
105101
/// <returns>The count of coordinates.</returns>
106102
[ExcludeFromCodeCoverage]
107103
[MethodImpl(MethodImplOptions.AggressiveInlining)]
108-
static int GetCount(IEnumerable<TCoordinate> coordinates) => coordinates switch {
109-
ICollection collection => collection.Count,
110-
//IEnumerable<TCoordinate> enumerable => enumerable.Count(),
104+
static int GetCount(IEnumerable<Coordinate> coordinates) => coordinates switch {
105+
ICollection<Coordinate> collection => collection.Count,
106+
IEnumerable<Coordinate> enumerable => enumerable.Count(),
111107
_ => -1,
112108
};
113109
}

src/PolylineAlgorithm/PolylineEncoding.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public bool TryWriteValue(int variance, ref Span<char> buffer, ref int position)
6060
}
6161

6262
[MethodImpl(MethodImplOptions.AggressiveInlining)]
63-
public int Normalize(double value) => Convert.ToInt32(value * Defaults.Algorithm.Precision);
63+
public int Normalize(double value) => (int)Math.Truncate(value * Defaults.Algorithm.Precision);
6464

6565
[MethodImpl(MethodImplOptions.AggressiveInlining)]
6666
public int GetCharCount(int variance) => variance switch {

tests/PolylineAlgorithm.Tests/PolylineDecoderTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class PolylineDecoderTest {
1818
/// <summary>
1919
/// The instance of the <see cref="PolylineDecoder"/> used for testing.
2020
/// </summary>
21-
public DefaultPolylineDecoder Decoder = new();
21+
public PolylineDecoder Decoder = new();
2222

2323
/// <summary>
2424
/// Tests the <see cref="PolylineDecoder.Decode(ref readonly Polyline)"/> method with an empty input, expecting an <see cref="ArgumentException"/>.

tests/PolylineAlgorithm.Tests/PolylineEncoderTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class PolylineEncoderTest {
1818
/// <summary>
1919
/// The instance of the <see cref="PolylineEncoder"/> used for testing.
2020
/// </summary>
21-
public DefaultPolylineEncoder Encoder = new();
21+
public PolylineEncoder Encoder = new();
2222

2323
/// <summary>
2424
/// Tests the <see cref="PolylineEncoder.Encode(IEnumerable{Coordinate})"/> method with a null input, expecting an <see cref="ArgumentNullException"/>.

utilities/PolylineAlgorithm.Utility/ValueProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
public static class ValueProvider {
99
private static readonly Random _random = new(DateTime.Now.Millisecond);
1010
private static readonly ConcurrentDictionary<int, CoordinatePair> _cache = new();
11-
private static readonly DefaultPolylineEncoder _encoder = new();
11+
private static readonly PolylineEncoder _encoder = new();
1212

1313
public static IEnumerable<Coordinate> GetCoordinates(int count) {
1414
var entry = GetCaheEntry(count);

0 commit comments

Comments
 (0)