Skip to content

Commit cada109

Browse files
authored
Optimized Field Merging (#6649)
1 parent 47a5319 commit cada109

File tree

10 files changed

+479
-86
lines changed

10 files changed

+479
-86
lines changed

.github/workflows/release.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- '12.*'
7+
8+
jobs:
9+
release:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout
13+
uses: actions/checkout@v3
14+
15+
- name: Install .NET
16+
uses: actions/setup-dotnet@v3
17+
with:
18+
dotnet-version: |
19+
6.x
20+
7.x
21+
8.x
22+
23+
- name: Get the version
24+
id: get_version
25+
run: echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
26+
27+
- name: Build Packages
28+
run: |
29+
./build.sh pack --SemVersion ${{ env.GIT_TAG }} --Configuration Release
30+
31+
- name: Push Packages
32+
run: |
33+
./build.cmd publish --skip
34+
env:
35+
NuGetApiKey: ${{ secrets.NUGETAPIKEY }}
36+
37+
- name: Get release
38+
id: get_release
39+
run: |
40+
RELEASE_ID=$(gh api repos/ChilliCream/graphql-platform/releases/tags/${{ env.GIT_TAG }} --jq '.id')
41+
UPLOAD_URL=$(gh api repos/ChilliCream/graphql-platform/releases/$RELEASE_ID --jq '.upload_url')
42+
echo "RELEASE_ID=$RELEASE_ID" >> $GITHUB_ENV
43+
echo "UPLOAD_URL=${UPLOAD_URL}" >> $GITHUB_ENV
44+
env:
45+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
46+
47+
- name: Upload Release Assets
48+
run: |
49+
for file in ./output/packages/*.nupkg; do
50+
echo "Uploading $file"
51+
gh release upload ${{ env.GIT_TAG }} "$file" --repo ChilliCream/graphql-platform
52+
done
53+
env:
54+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

src/HotChocolate/Core/src/Types/Types/Extensions/TypeExtensions.cs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Runtime.CompilerServices;
34
using HotChocolate.Language;
45
using HotChocolate.Properties;
56
using static HotChocolate.Utilities.ThrowHelper;
@@ -190,21 +191,64 @@ public static bool IsNamedType(this IType type)
190191
}
191192
}
192193

194+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
193195
internal static bool IsType(this IType type, TypeKind kind)
194196
{
195197
if (type.Kind == kind)
196198
{
197199
return true;
198200
}
199201

200-
if (type.Kind == TypeKind.NonNull && ((NonNullType)type).Type.Kind == kind)
202+
if (type.Kind == TypeKind.NonNull && ((NonNullType) type).Type.Kind == kind)
201203
{
202204
return true;
203205
}
204206

205207
return false;
206208
}
207209

210+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
211+
internal static bool IsType(this IType type, TypeKind kind1, TypeKind kind2)
212+
{
213+
if (type.Kind == kind1 || type.Kind == kind2)
214+
{
215+
return true;
216+
}
217+
218+
if (type.Kind == TypeKind.NonNull)
219+
{
220+
var innerKind = ((NonNullType) type).Type.Kind;
221+
222+
if (innerKind == kind1 || innerKind == kind2)
223+
{
224+
return true;
225+
}
226+
}
227+
228+
return false;
229+
}
230+
231+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
232+
internal static bool IsType(this IType type, TypeKind kind1, TypeKind kind2, TypeKind kind3)
233+
{
234+
if (type.Kind == kind1 || type.Kind == kind2 || type.Kind == kind3)
235+
{
236+
return true;
237+
}
238+
239+
if (type.Kind == TypeKind.NonNull)
240+
{
241+
var innerKind = ((NonNullType) type).Type.Kind;
242+
243+
if (innerKind == kind1 || innerKind == kind2 || innerKind == kind3)
244+
{
245+
return true;
246+
}
247+
}
248+
249+
return false;
250+
}
251+
208252
public static IType InnerType(this IType type)
209253
{
210254
if (type is null)

src/HotChocolate/Core/src/Validation/DocumentValidatorContext.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ public IOutputType NonNullString
100100

101101
public IDictionary<string, object?> ContextData { get; set; } = default!;
102102

103+
public List<FieldInfoPair> CurrentFieldPairs { get; } = new();
104+
105+
public List<FieldInfoPair> NextFieldPairs { get; } = new();
106+
107+
public HashSet<FieldInfoPair> ProcessedFieldPairs { get; } = new();
108+
103109
public IList<FieldInfo> RentFieldInfoList()
104110
{
105111
FieldInfoListBuffer buffer = _buffers.Peek();

src/HotChocolate/Core/src/Validation/ErrorHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ public static IError FieldIsRequiredButNull(
261261
.Build();
262262
}
263263

264-
public static IError FieldsAreNotMergable(
264+
public static IError FieldsAreNotMergeable(
265265
this IDocumentValidatorContext context,
266266
FieldInfo fieldA,
267267
FieldInfo fieldB)

src/HotChocolate/Core/src/Validation/FieldInfo.cs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using HotChocolate.Language;
23
using HotChocolate.Types;
34

@@ -7,7 +8,7 @@ namespace HotChocolate.Validation;
78
/// The validation field info provides access to the field node and the type
89
/// information of the referenced field.
910
/// </summary>
10-
public readonly struct FieldInfo
11+
public readonly struct FieldInfo : IEquatable<FieldInfo>
1112
{
1213
/// <summary>
1314
/// Initializes a new instance of <see cref="FieldInfo"/>
@@ -41,4 +42,39 @@ public FieldInfo(IType declaringType, IType type, FieldNode field)
4142
/// Gets the field selection.
4243
/// </summary>
4344
public FieldNode Field { get; }
45+
46+
/// <summary>
47+
/// Compares this field info to another field info.
48+
/// </summary>
49+
/// <param name="other">
50+
/// The other field info.
51+
/// </param>
52+
/// <returns>
53+
/// <c>true</c> if the field infos are equal.
54+
/// </returns>
55+
public bool Equals(FieldInfo other)
56+
=> Field.Equals(other.Field) &&
57+
DeclaringType.Equals(other.DeclaringType) &&
58+
Type.Equals(other.Type);
59+
60+
/// <summary>
61+
/// Compares this field info to another object.
62+
/// </summary>
63+
/// <param name="obj">
64+
/// The other object.
65+
/// </param>
66+
/// <returns>
67+
/// <c>true</c> if the field infos are equal.
68+
/// </returns>
69+
public override bool Equals(object? obj)
70+
=> obj is FieldInfo other && Equals(other);
71+
72+
/// <summary>
73+
/// Returns the hash code of this instance.
74+
/// </summary>
75+
/// <returns>
76+
/// The hash code of this instance.
77+
/// </returns>
78+
public override int GetHashCode()
79+
=> HashCode.Combine(Field, DeclaringType, Type);
4480
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using System;
2+
3+
namespace HotChocolate.Validation;
4+
5+
/// <summary>
6+
/// Represents a pair of field infos.
7+
/// </summary>
8+
public readonly struct FieldInfoPair : IEquatable<FieldInfoPair>
9+
{
10+
/// <summary>
11+
/// Initializes a new instance of <see cref="FieldInfoPair"/>.
12+
/// </summary>
13+
/// <param name="fieldA">
14+
/// The first field info.
15+
/// </param>
16+
/// <param name="fieldB">
17+
/// The second field info.
18+
/// </param>
19+
public FieldInfoPair(FieldInfo fieldA, FieldInfo fieldB)
20+
{
21+
FieldA = fieldA;
22+
FieldB = fieldB;
23+
}
24+
25+
/// <summary>
26+
/// Gets the first field info.
27+
/// </summary>
28+
public FieldInfo FieldA { get; }
29+
30+
/// <summary>
31+
/// Gets the second field info.
32+
/// </summary>
33+
public FieldInfo FieldB { get; }
34+
35+
/// <summary>
36+
/// Compares this field info pair to another field info pair.
37+
/// </summary>
38+
/// <param name="other">
39+
/// The other field info pair.
40+
/// </param>
41+
/// <returns>
42+
/// <c>true</c> if the field info pairs are equal.
43+
/// </returns>
44+
public bool Equals(FieldInfoPair other)
45+
=> FieldA.Equals(other.FieldA) && FieldB.Equals(other.FieldB);
46+
47+
/// <summary>
48+
/// Compares this field info pair to another object.
49+
/// </summary>
50+
/// <param name="obj">
51+
/// The other object.
52+
/// </param>
53+
/// <returns>
54+
/// <c>true</c> if the field info pairs are equal.
55+
/// </returns>
56+
public override bool Equals(object? obj)
57+
=> obj is FieldInfoPair other && Equals(other);
58+
59+
/// <summary>
60+
/// Returns the hash code for this field info pair.
61+
/// </summary>
62+
/// <returns>
63+
/// The hash code for this field info pair.
64+
/// </returns>
65+
public override int GetHashCode()
66+
=> HashCode.Combine(FieldA, FieldB);
67+
}

src/HotChocolate/Core/src/Validation/HotChocolate.Validation.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<ItemGroup>
2323
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.4" />
2424
<PackageReference Include="Microsoft.Extensions.Options" Version="3.1.4" />
25+
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
2526
</ItemGroup>
2627

2728
<ItemGroup>

src/HotChocolate/Core/src/Validation/IDocumentValidatorContext.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,21 @@ public interface IDocumentValidatorContext : ISyntaxVisitorContext
145145
/// </summary>
146146
IDictionary<string, object?> ContextData { get; }
147147

148+
/// <summary>
149+
/// When processing field merging this list holds the field pairs that are processed.
150+
/// </summary>
151+
List<FieldInfoPair> CurrentFieldPairs { get; }
152+
153+
/// <summary>
154+
/// When processing field merging this list holds the field pairs that are processed next.
155+
/// </summary>
156+
List<FieldInfoPair> NextFieldPairs { get; }
157+
158+
/// <summary>
159+
/// When processing field merging this set represents the already processed field pairs.
160+
/// </summary>
161+
HashSet<FieldInfoPair> ProcessedFieldPairs { get; }
162+
148163
/// <summary>
149164
/// Rents a list of field infos.
150165
/// </summary>

0 commit comments

Comments
 (0)