Skip to content

Commit e99ec77

Browse files
committed
Make stringset rely on MarshallHelper
1 parent 65bef5c commit e99ec77

File tree

7 files changed

+128
-25
lines changed

7 files changed

+128
-25
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ Here's a quick summary about how this library performs with a quick example of m
4040

4141
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
4242
|---------------------------- |-----------:|---------:|---------:|-------:|-------:|----------:|
43-
| Marshall_AWS_Reflection | 5,351.9 ns | 74.57 ns | 69.75 ns | 0.8545 | - | 10875 B |
44-
| Marshall_Source_Generated | 488.9 ns | 8.21 ns | 7.68 ns | 0.2375 | 0.0019 | 2984 B |
45-
| Unmarshall_AWS_Reflection | 5,447.3 ns | 68.30 ns | 63.89 ns | 0.8545 | - | 10922 B |
46-
| Unmarshall_Source_Generated | 923.6 ns | 10.92 ns | 10.21 ns | 0.0610 | - | 768 B |
43+
| Marshall_AWS_Reflection | 5,841.5 ns | 87.91 ns | 82.23 ns | 0.8850 | - | 11309 B |
44+
| Marshall_Source_Generated | 508.5 ns | 9.08 ns | 19.16 ns | 0.2384 | 0.0019 | 3000 B |
45+
| Unmarshall_AWS_Reflection | 6,164.6 ns | 43.43 ns | 40.62 ns | 0.8850 | - | 11274 B |
46+
| Unmarshall_Source_Generated | 814.9 ns | 14.09 ns | 13.18 ns | 0.0305 | - | 392 B |
4747

4848
## Features:
4949

src/DynamoDBGenerator.SourceGenerator/Constants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ public static class AttributeValueUtilityFactory
9797
public const string FromNullableStringSet = $"{ClassName}.FromNullableStringSet";
9898
public const string FromNumberSet = $"{ClassName}.FromNumberSet";
9999
public const string FromNullableNumberSet = $"{ClassName}.FromNullableNumberSet";
100+
public const string ToNullableStringSet = $"{ClassName}.ToNullableStringSet";
100101
}
101102
public static class ExceptionHelper
102103
{

src/DynamoDBGenerator.SourceGenerator/Generations/UnMarshaller.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ private static CodeFactory CreateMethod(TypeIdentifier typeIdentifier, Func<ITyp
132132
.CreateScope(
133133
$"if ({Value} is null || {Value}.SS is null)"
134134
.CreateScope(singleGeneric.ReturnNullOrThrow(DataMember))
135-
.Append($"return new {(singleGeneric.TypeSymbol.TypeKind is TypeKind.Interface ? $"HashSet<{(singleGeneric.T.IsSupposedToBeNull ? "string?" : "string")}>" : null)}({(singleGeneric.T.IsSupposedToBeNull ? $"{Value}.SS" : $"{Value}.SS.Select((y,i) => y ?? throw {ExceptionHelper.NullExceptionMethod}($\"{{{DataMember}}}[UNKNOWN]\"))")});")
135+
.Append($"return {AttributeValueUtilityFactory.ClassName}.{(singleGeneric.T.IsSupposedToBeNull ? $"ToNullableString{typeIdentifier.TypeSymbol.Name}" : $"ToString{typeIdentifier.TypeSymbol.Name}")}({Value}.SS, {DataMember});")
136136
)
137137
.ToConversion(),
138138
SingleGeneric.SupportedType.Set when singleGeneric.T.IsNumeric => signature

src/DynamoDBGenerator/Internal/MarshallHelper.cs

Lines changed: 101 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
using System.Diagnostics.CodeAnalysis;
44
using System.Linq;
55
using System.Numerics;
6-
using System.Runtime.CompilerServices;
6+
using System.Runtime.InteropServices;
77
using Amazon.DynamoDBv2.Model;
8-
using static System.Runtime.InteropServices.CollectionsMarshal;
98

109
namespace DynamoDBGenerator.Internal;
1110

@@ -145,6 +144,43 @@ public static AttributeValue FromStringSet(IEnumerable<string> strings, string?
145144
}
146145
}
147146

147+
private static TSet ToStringSet<TSet>(
148+
List<string> numbers,
149+
Func<int, TSet> factory,
150+
string? dataMember
151+
)
152+
where TSet : ICollection<string>
153+
{
154+
var span = CollectionsMarshal.AsSpan(numbers);
155+
var set = factory(span.Length);
156+
157+
foreach (var @string in span)
158+
{
159+
if (@string is null)
160+
throw ExceptionHelper.NotNull($"{dataMember}[UNKNOWN]");
161+
162+
set.Add(@string);
163+
}
164+
165+
return set;
166+
}
167+
168+
private static TSet ToNullableStringSet<TSet>(
169+
List<string?> numbers,
170+
Func<int, TSet> factory,
171+
string? _
172+
)
173+
where TSet : ICollection<string?>
174+
{
175+
var span = CollectionsMarshal.AsSpan(numbers);
176+
var set = factory(span.Length);
177+
178+
foreach (var @string in span)
179+
set.Add(@string);
180+
181+
return set;
182+
}
183+
148184
private static TSet ToNumberSet<TNumber, TSet>(
149185
List<string> numbers,
150186
Func<int, TSet> factory,
@@ -153,7 +189,7 @@ private static TSet ToNumberSet<TNumber, TSet>(
153189
where TSet : ICollection<TNumber>
154190
where TNumber : struct, INumber<TNumber>
155191
{
156-
var span = AsSpan(numbers);
192+
var span = CollectionsMarshal.AsSpan(numbers);
157193
var set = factory(span.Length);
158194

159195
foreach (var number in span)
@@ -166,7 +202,7 @@ private static TSet ToNumberSet<TNumber, TSet>(
166202

167203
return set;
168204
}
169-
205+
170206
private static TSet ToNullableNumberSet<TNumber, TSet>(
171207
List<string?> numbers,
172208
Func<int, TSet> factory,
@@ -175,7 +211,7 @@ private static TSet ToNullableNumberSet<TNumber, TSet>(
175211
where TSet : ICollection<TNumber?>
176212
where TNumber : struct, INumber<TNumber>
177213
{
178-
var span = AsSpan(numbers);
214+
var span = CollectionsMarshal.AsSpan(numbers);
179215
var set = factory(span.Length);
180216

181217
foreach (var number in span)
@@ -189,6 +225,60 @@ private static TSet ToNullableNumberSet<TNumber, TSet>(
189225
return set;
190226
}
191227

228+
public static ISet<string> ToStringISet(List<string> ss, string? dataMember)
229+
{
230+
return ToStringSet<HashSet<string>>(ss, i => new HashSet<string>(i), dataMember);
231+
}
232+
233+
public static IReadOnlySet<string> ToStringIReadOnlySet(List<string> ss, string? dataMember)
234+
{
235+
return ToStringSet<HashSet<string>>(ss, i => new HashSet<string>(i), dataMember);
236+
}
237+
238+
public static HashSet<string> ToStringHashSet(List<string> ss, string? dataMember)
239+
{
240+
return ToStringSet<HashSet<string>>(ss, i => new HashSet<string>(i), dataMember);
241+
}
242+
243+
public static ISet<string?> ToNullableStringISet(List<string?> ss, string? dataMember)
244+
{
245+
return ToNullableStringSet<HashSet<string?>>(ss, i => new HashSet<string?>(i), dataMember);
246+
}
247+
248+
public static IReadOnlySet<string?> ToNullableStringIReadOnlySet(List<string?> ss, string? dataMember)
249+
{
250+
return ToNullableStringSet<HashSet<string?>>(ss, i => new HashSet<string?>(i), dataMember);
251+
}
252+
253+
public static HashSet<string?> ToNullableStringHashSet(List<string?> ss, string? dataMember)
254+
{
255+
return ToNullableStringSet<HashSet<string?>>(ss, i => new HashSet<string?>(i), dataMember);
256+
}
257+
258+
public static SortedSet<string?> ToNullableStringSortedSet(List<string?> ss, string? _)
259+
{
260+
var span = CollectionsMarshal.AsSpan(ss);
261+
var set = new SortedSet<string?>();
262+
foreach (var se in span)
263+
set.Add(se);
264+
265+
return set;
266+
}
267+
public static SortedSet<string> ToStringSortedSet(List<string> ss, string? dataMember)
268+
{
269+
var span = CollectionsMarshal.AsSpan(ss);
270+
var set = new SortedSet<string>();
271+
foreach (var se in span)
272+
{
273+
if (se is null)
274+
throw ExceptionHelper.NotNull($"{dataMember}[UNKNOWN]");
275+
276+
set.Add(se);
277+
}
278+
279+
return set;
280+
}
281+
192282
public static ISet<TNumber> ToNumberISet<TNumber>(List<string> ns, string? dataMember)
193283
where TNumber : struct, INumber<TNumber>
194284
{
@@ -201,16 +291,16 @@ public static IReadOnlySet<TNumber> ToNumberIReadOnlySet<TNumber>(List<string> n
201291
return ToNumberSet<TNumber, HashSet<TNumber>>(ns, i => new HashSet<TNumber>(i), dataMember);
202292
}
203293

204-
public static HashSet<TNumber> ToNumberHashSet<TNumber>(List<string> ns, string? dataMember)
294+
public static HashSet<TNumber> ToNumberHashSet<TNumber>(List<string> ss, string? dataMember)
205295
where TNumber : struct, INumber<TNumber>
206296
{
207-
return ToNumberSet<TNumber, HashSet<TNumber>>(ns, i => new HashSet<TNumber>(i), dataMember);
297+
return ToNumberSet<TNumber, HashSet<TNumber>>(ss, i => new HashSet<TNumber>(i), dataMember);
208298
}
209299

210300
public static SortedSet<TNumber> ToNumberSortedSet<TNumber>(List<string> ns, string? dataMember)
211301
where TNumber : struct, INumber<TNumber>
212302
{
213-
var span = AsSpan(ns);
303+
var span = CollectionsMarshal.AsSpan(ns);
214304
var set = new SortedSet<TNumber>();
215305
foreach (var se in span)
216306
{
@@ -321,7 +411,7 @@ public static AttributeValue FromList<T, TArgument>(
321411
string? dataMember,
322412
Func<T, TArgument, string?, AttributeValue> resultSelector)
323413
{
324-
var span = AsSpan(list);
414+
var span = CollectionsMarshal.AsSpan(list);
325415
var attributeValues = new List<AttributeValue>(span.Length);
326416
for (var i = 0; i < span.Length; i++)
327417
attributeValues.Add(resultSelector(span[i], argument, $"{dataMember}[{i}]"));
@@ -358,7 +448,7 @@ public static List<TResult> ToList<TResult, TArgument>(
358448
Func<AttributeValue, TArgument, string?, TResult> resultSelector
359449
)
360450
{
361-
var span = AsSpan(attributeValues);
451+
var span = CollectionsMarshal.AsSpan(attributeValues);
362452
var elements = new List<TResult>(span.Length);
363453
for (var i = 0; i < span.Length; i++)
364454
elements.Add(resultSelector(span[i], argument, $"{dataMember}[{i}]"));
@@ -384,7 +474,7 @@ public static TResult[] ToArray<TResult, TArgument>(
384474
Func<AttributeValue, TArgument, string?, TResult> resultSelector
385475
)
386476
{
387-
var span = AsSpan(attributeValues);
477+
var span = CollectionsMarshal.AsSpan(attributeValues);
388478
var elements = new TResult[span.Length];
389479
for (var i = 0; i < span.Length; i++)
390480
elements[i] = resultSelector(span[i], argument, $"{dataMember}[{i}]");

tests/DynamoDBGenerator.SourceGenerator.Benchmarks/Models/PersonEntity.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ namespace DynamoDBGenerator.SourceGenerator.Benchmarks.Models;
66
[DynamoDBMarshaller(EntityType = typeof(PersonEntity))]
77
public partial record PersonEntity
88
{
9+
public HashSet<string?>? StringSet { get; set; }
10+
public HashSet<int?>? IntSet { get; set; }
911
[DynamoDBHashKey]
1012
public string Id { get; set; } = null!;
1113

@@ -16,6 +18,4 @@ public partial record PersonEntity
1618
public DateTime InsertedAt { get; set; }
1719
public DateTime? DeletedAt { get; set; }
1820
public Address Address { get; set; } = null!;
19-
public HashSet<string> StringSet { get; set; }
20-
public HashSet<int> IntSet { get; set; }
2121
}

tests/DynamoDBGenerator.SourceGenerator.Benchmarks/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Job=.NET 8.0 Runtime=.NET 8.0
1212

1313
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
1414
|---------------------------- |-----------:|---------:|---------:|-------:|-------:|----------:|
15-
| Marshall_AWS_Reflection | 5,351.9 ns | 74.57 ns | 69.75 ns | 0.8545 | - | 10875 B |
16-
| Marshall_Source_Generated | 488.9 ns | 8.21 ns | 7.68 ns | 0.2375 | 0.0019 | 2984 B |
17-
| Unmarshall_AWS_Reflection | 5,447.3 ns | 68.30 ns | 63.89 ns | 0.8545 | - | 10922 B |
18-
| Unmarshall_Source_Generated | 923.6 ns | 10.92 ns | 10.21 ns | 0.0610 | - | 768 B |
15+
| Marshall_AWS_Reflection | 5,841.5 ns | 87.91 ns | 82.23 ns | 0.8850 | - | 11309 B |
16+
| Marshall_Source_Generated | 508.5 ns | 9.08 ns | 19.16 ns | 0.2384 | 0.0019 | 3000 B |
17+
| Unmarshall_AWS_Reflection | 6,164.6 ns | 43.43 ns | 40.62 ns | 0.8850 | - | 11274 B |
18+
| Unmarshall_Source_Generated | 814.9 ns | 14.09 ns | 13.18 ns | 0.0305 | - | 392 B |

tests/DynamoDBGenerator.SourceGenerator.Tests/DynamoDBDocumentTests/Marshaller/Asserters/MarshalAsserter.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,33 @@ public abstract class MarshalAsserter<T>
1212
public void Marshall()
1313
{
1414
Arguments().Should()
15-
.AllSatisfy(x => MarshallImplementation(x.element).Should().BeEquivalentTo(x.attributeValues));
15+
.AllSatisfy(x =>
16+
{
17+
var marshallImplementation = MarshallImplementation(x.element);
18+
marshallImplementation.Should().BeEquivalentTo(x.attributeValues);
19+
});
1620
}
1721

1822
[Fact]
1923
public void Unmarshall()
2024
{
2125
Arguments().Should()
22-
.AllSatisfy(x => UnmarshallImplementation(x.attributeValues).Should().BeEquivalentTo(x.element));
26+
.AllSatisfy(x =>
27+
{
28+
var unmarshallImplementation = UnmarshallImplementation(x.attributeValues);
29+
unmarshallImplementation.Should().BeEquivalentTo(x.element);
30+
});
2331
}
2432

2533
[Fact]
2634
public void Marshall_IsEquivalentTo_UnmarshallResult()
2735
{
2836
Arguments().Should().AllSatisfy(x =>
29-
UnmarshallImplementation(MarshallImplementation(x.element)).Should().BeEquivalentTo(x.element));
37+
{
38+
var marshalImplementation = MarshallImplementation(x.element);
39+
var unmarshallImplementation = UnmarshallImplementation(marshalImplementation);
40+
unmarshallImplementation.Should().BeEquivalentTo(x.element);
41+
});
3042
}
3143

3244
[Fact]

0 commit comments

Comments
 (0)