Skip to content

Commit 48f8954

Browse files
author
Bart Koelman
committed
Changed SparseFieldTableExpression.Table type from IReadOnlyDictionary to IImmutableDictionary and fixed equality comparison to discard order
1 parent b408bad commit 48f8954

File tree

4 files changed

+51
-11
lines changed

4 files changed

+51
-11
lines changed

src/JsonApiDotNetCore/CollectionExtensions.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,41 @@ public static int FindIndex<T>(this IList<T> source, Predicate<T> match)
3434

3535
return -1;
3636
}
37+
38+
public static bool DictionaryEqual<TKey, TValue>(this IReadOnlyDictionary<TKey, TValue> first, IReadOnlyDictionary<TKey, TValue> second,
39+
IEqualityComparer<TValue> valueComparer = null)
40+
{
41+
if (first == second)
42+
{
43+
return true;
44+
}
45+
46+
if (first == null || second == null)
47+
{
48+
return false;
49+
}
50+
51+
if (first.Count != second.Count)
52+
{
53+
return false;
54+
}
55+
56+
IEqualityComparer<TValue> effectiveValueComparer = valueComparer ?? EqualityComparer<TValue>.Default;
57+
58+
foreach ((TKey firstKey, TValue firstValue) in first)
59+
{
60+
if (!second.TryGetValue(firstKey, out TValue secondValue))
61+
{
62+
return false;
63+
}
64+
65+
if (!effectiveValueComparer.Equals(firstValue, secondValue))
66+
{
67+
return false;
68+
}
69+
}
70+
71+
return true;
72+
}
3773
}
3874
}

src/JsonApiDotNetCore/Queries/Expressions/QueryExpressionRewriter.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
using System.Collections.Immutable;
23
using System.Linq;
34
using JetBrains.Annotations;
45
using JsonApiDotNetCore.Configuration;
@@ -198,7 +199,8 @@ public override QueryExpression VisitSparseFieldTable(SparseFieldTableExpression
198199
{
199200
if (expression != null)
200201
{
201-
var newTable = new Dictionary<ResourceContext, SparseFieldSetExpression>();
202+
ImmutableDictionary<ResourceContext, SparseFieldSetExpression>.Builder newTable =
203+
ImmutableDictionary.CreateBuilder<ResourceContext, SparseFieldSetExpression>();
202204

203205
foreach ((ResourceContext resourceContext, SparseFieldSetExpression sparseFieldSet) in expression.Table)
204206
{
@@ -210,7 +212,7 @@ public override QueryExpression VisitSparseFieldTable(SparseFieldTableExpression
210212

211213
if (newTable.Count > 0)
212214
{
213-
var newExpression = new SparseFieldTableExpression(newTable);
215+
var newExpression = new SparseFieldTableExpression(newTable.ToImmutable());
214216
return newExpression.Equals(expression) ? expression : newExpression;
215217
}
216218
}

src/JsonApiDotNetCore/Queries/Expressions/SparseFieldTableExpression.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
2+
using System.Collections.Immutable;
43
using System.Text;
54
using JetBrains.Annotations;
65
using JsonApiDotNetCore.Configuration;
@@ -13,9 +12,9 @@ namespace JsonApiDotNetCore.Queries.Expressions
1312
[PublicAPI]
1413
public class SparseFieldTableExpression : QueryExpression
1514
{
16-
public IReadOnlyDictionary<ResourceContext, SparseFieldSetExpression> Table { get; }
15+
public IImmutableDictionary<ResourceContext, SparseFieldSetExpression> Table { get; }
1716

18-
public SparseFieldTableExpression(IReadOnlyDictionary<ResourceContext, SparseFieldSetExpression> table)
17+
public SparseFieldTableExpression(IImmutableDictionary<ResourceContext, SparseFieldSetExpression> table)
1918
{
2019
ArgumentGuard.NotNullNorEmpty(table, nameof(table), "entries");
2120

@@ -61,7 +60,7 @@ public override bool Equals(object obj)
6160

6261
var other = (SparseFieldTableExpression)obj;
6362

64-
return Table.SequenceEqual(other.Table);
63+
return Table.DictionaryEqual(other.Table);
6564
}
6665

6766
public override int GetHashCode()

src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ public class SparseFieldSetQueryStringParameterReader : QueryStringParameterRead
2121
{
2222
private readonly SparseFieldTypeParser _sparseFieldTypeParser;
2323
private readonly SparseFieldSetParser _sparseFieldSetParser;
24-
private readonly Dictionary<ResourceContext, SparseFieldSetExpression> _sparseFieldTable = new();
24+
25+
private readonly ImmutableDictionary<ResourceContext, SparseFieldSetExpression>.Builder _sparseFieldTableBuilder =
26+
ImmutableDictionary.CreateBuilder<ResourceContext, SparseFieldSetExpression>();
27+
2528
private string _lastParameterName;
2629

2730
/// <inheritdoc />
@@ -69,7 +72,7 @@ public virtual void Read(string parameterName, StringValues parameterValue)
6972
ResourceContext targetResource = GetSparseFieldType(parameterName);
7073
SparseFieldSetExpression sparseFieldSet = GetSparseFieldSet(parameterValue, targetResource);
7174

72-
_sparseFieldTable[targetResource] = sparseFieldSet;
75+
_sparseFieldTableBuilder[targetResource] = sparseFieldSet;
7376
}
7477
catch (QueryParseException exception)
7578
{
@@ -99,8 +102,8 @@ private SparseFieldSetExpression GetSparseFieldSet(string parameterValue, Resour
99102
/// <inheritdoc />
100103
public virtual IReadOnlyCollection<ExpressionInScope> GetConstraints()
101104
{
102-
return _sparseFieldTable.Any()
103-
? new ExpressionInScope(null, new SparseFieldTableExpression(_sparseFieldTable)).AsArray()
105+
return _sparseFieldTableBuilder.Any()
106+
? new ExpressionInScope(null, new SparseFieldTableExpression(_sparseFieldTableBuilder.ToImmutable())).AsArray()
104107
: Array.Empty<ExpressionInScope>();
105108
}
106109
}

0 commit comments

Comments
 (0)