Skip to content

Commit

Permalink
Fix key comparison for more than 10 elements in AdaptiveCapacityDicti…
Browse files Browse the repository at this point in the history
…onary (dotnet#35685)
  • Loading branch information
BrennanConroy authored Aug 25, 2021
1 parent ad94c56 commit 52de4ad
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 2 deletions.
34 changes: 34 additions & 0 deletions src/Http/Http/test/Features/QueryFeatureTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,5 +220,39 @@ public void ParseQueryWithEncodedKeyEncodedValuesWorks()
Assert.Single(queryCollection);
Assert.Equal(new[] { "[ 1 ]", "[ 2 ]" }, queryCollection["fields [todoItems]"]);
}

[Fact]
public void CaseInsensitiveWithManyKeys()
{
// need to use over 10 keys to test dictionary storage code path
var features = new FeatureCollection();
features[typeof(IHttpRequestFeature)] = new HttpRequestFeature
{
QueryString = "?a=0&b=0&c=1&d=2&e=3&f=4&g=5&h=6&i=7&j=8&k=9&" +
"key=1&Key=2&key=3&Key=4&KEy=5&KEY=6&kEY=7&KeY=8&kEy=9&keY=10"
};

var provider = new QueryFeature(features);

var queryCollection = provider.Query;

Assert.Equal(12, queryCollection.Count);
Assert.Equal(new[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" }, queryCollection["KEY"]);
}

[Fact]
public void CaseInsensitiveWithFewKeys()
{
// need to use less than 10 keys to test array storage code path
var features = new FeatureCollection();
features[typeof(IHttpRequestFeature)] = new HttpRequestFeature { QueryString = "?key=1&Key=2&key=3&Key=4&KEy=5" };

var provider = new QueryFeature(features);

var queryCollection = provider.Query;

Assert.Equal(1, queryCollection.Count);
Assert.Equal(new[] { "1", "2", "3", "4", "5" }, queryCollection["KEY"]);
}
}
}
4 changes: 2 additions & 2 deletions src/Shared/Dictionary/AdaptiveCapacityDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public AdaptiveCapacityDictionary(int capacity, IEqualityComparer<TKey> comparer
}
else
{
_dictionaryStorage = new Dictionary<TKey, TValue>(capacity);
_dictionaryStorage = new Dictionary<TKey, TValue>(capacity, _comparer);
}
}

Expand Down Expand Up @@ -519,7 +519,7 @@ private void EnsureCapacitySlow(int capacity)

if (capacity > DefaultArrayThreshold)
{
_dictionaryStorage = new Dictionary<TKey, TValue>(capacity);
_dictionaryStorage = new Dictionary<TKey, TValue>(capacity, _comparer);
foreach (var item in _arrayStorage)
{
_dictionaryStorage[item.Key] = item.Value;
Expand Down
36 changes: 36 additions & 0 deletions src/Shared/test/Shared.Tests/AdaptiveCapacityDictionaryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1279,6 +1279,42 @@ public void ListStorage_RemoveAt_RearrangesInnerArray()
Assert.Equal("value3", storage[1].Value);
}

[Fact]
public void UpgradeToDictionary_KeepsComparer()
{
// Arrange
var comparer = StringComparer.OrdinalIgnoreCase;
var dict = new AdaptiveCapacityDictionary<string, object>(StringComparer.OrdinalIgnoreCase);
for (var i = 0; i < 11; i++)
{
dict[i.ToString()] = i;
}

Assert.NotNull(dict._dictionaryStorage);
Assert.Equal(comparer, dict._dictionaryStorage.Comparer);

dict["K"] = 1;
dict["k"] = 2;

Assert.Equal(2, dict["K"]);
}

[Fact]
public void StartAsDictionary_UsesComparer()
{
// Arrange
var comparer = StringComparer.OrdinalIgnoreCase;
var dict = new AdaptiveCapacityDictionary<string, object>(11, StringComparer.OrdinalIgnoreCase);

Assert.NotNull(dict._dictionaryStorage);
Assert.Equal(comparer, dict._dictionaryStorage.Comparer);

dict["K"] = 1;
dict["k"] = 2;

Assert.Equal(2, dict["K"]);
}

private void AssertEmptyArrayStorage(AdaptiveCapacityDictionary<string, string> value)
{
Assert.Same(Array.Empty<KeyValuePair<string, object?>>(), value._arrayStorage);
Expand Down

0 comments on commit 52de4ad

Please sign in to comment.