Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement new metadata knobs as internal APIs #71449

Merged
merged 2 commits into from
Jun 30, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions src/libraries/System.Text.Json/Common/JsonHelpers.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;
using System.Collections.Generic;

namespace System.Text.Json
Expand All @@ -22,6 +23,42 @@ public static bool TryAdd<TKey, TValue>(this Dictionary<TKey, TValue> dictionary
return false;
#else
return dictionary.TryAdd(key, value);
#endif
}

/// <summary>
/// Provides an in-place, stable sorting implementation for List.
/// </summary>
internal static void StableSortByKey<T, TKey>(this List<T> items, Func<T, TKey> keySelector)
eiriktsarpalis marked this conversation as resolved.
Show resolved Hide resolved
where TKey : unmanaged, IComparable<TKey>
{
#if NET6_0_OR_GREATER
Span<T> span = CollectionsMarshal.AsSpan(items);

// Tuples implement lexical ordering OOTB which can be used to encode stable sorting
// using the actual key as the first element and index as the second element.
const int StackallocThreshold = 32;
Span<(TKey, int)> keys = span.Length <= StackallocThreshold
? (stackalloc (TKey, int)[StackallocThreshold]).Slice(0, span.Length)
: new (TKey, int)[span.Length];

for (int i = 0; i < keys.Length; i++)
{
keys[i] = (keySelector(span[i]), i);
}

MemoryExtensions.Sort(keys, span);
#else
T[] arrayCopy = items.ToArray();
(TKey, int)[] keys = new (TKey, int)[arrayCopy.Length];
for (int i = 0; i < keys.Length; i++)
{
keys[i] = (keySelector(items[i]), i);
eiriktsarpalis marked this conversation as resolved.
Show resolved Hide resolved
}

Array.Sort(keys, arrayCopy);
items.Clear();
items.AddRange(arrayCopy);
#endif
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
Expand All @@ -16,7 +15,6 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.DotnetRuntime.Extensions;
using Microsoft.CodeAnalysis.Text;

namespace System.Text.Json.SourceGeneration
{
Expand Down
3 changes: 3 additions & 0 deletions src/libraries/System.Text.Json/src/Resources/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -668,4 +668,7 @@
<data name="JsonPolymorphismOptionsAssociatedWithDifferentJsonTypeInfo" xml:space="preserve">
<value>Parameter already associated with a different JsonTypeInfo instance.</value>
</data>
<data name="SerializationCallbacksNotSupported" xml:space="preserve">
<value>Serialization callbacks are not supported in metadata kind '{0}'.</value>
</data>
</root>
1 change: 1 addition & 0 deletions src/libraries/System.Text.Json/src/System.Text.Json.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ The System.Text.Json library is built-in as part of the shared framework in .NET
<Reference Include="System.Reflection.Emit.Lightweight" />
<Reference Include="System.Reflection.Primitives" />
<Reference Include="System.Runtime" />
<Reference Include="System.Runtime.InteropServices" />
<Reference Include="System.Runtime.Loader" />
<Reference Include="System.Text.Encoding.Extensions" />
<Reference Include="System.Threading" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public KeyCollection(JsonPropertyDictionary<T> jsonObject)

IEnumerator IEnumerable.GetEnumerator()
{
foreach (KeyValuePair<string, T?> item in _parent)
foreach (KeyValuePair<string, T> item in _parent)
{
yield return item.Key;
}
Expand All @@ -49,7 +49,7 @@ public void CopyTo(string[] propertyNameArray, int index)
ThrowHelper.ThrowArgumentOutOfRangeException_ArrayIndexNegative(nameof(index));
}

foreach (KeyValuePair<string, T?> item in _parent)
foreach (KeyValuePair<string, T> item in _parent)
{
if (index >= propertyNameArray.Length)
{
Expand All @@ -62,7 +62,7 @@ public void CopyTo(string[] propertyNameArray, int index)

public IEnumerator<string> GetEnumerator()
{
foreach (KeyValuePair<string, T?> item in _parent)
foreach (KeyValuePair<string, T> item in _parent)
{
yield return item.Key;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ internal sealed partial class JsonPropertyDictionary<T>
{
private ValueCollection? _valueCollection;

public ICollection<T?> GetValueCollection()
public ICollection<T> GetValueCollection()
{
return _valueCollection ??= new ValueCollection(this);
}

private sealed class ValueCollection : ICollection<T?>
private sealed class ValueCollection : ICollection<T>
{
private readonly JsonPropertyDictionary<T> _parent;

Expand All @@ -30,26 +30,26 @@ public ValueCollection(JsonPropertyDictionary<T> jsonObject)

IEnumerator IEnumerable.GetEnumerator()
{
foreach (KeyValuePair<string, T?> item in _parent)
foreach (KeyValuePair<string, T> item in _parent)
{
yield return item.Value;
}
}

public void Add(T? jsonNode) => ThrowHelper.ThrowNotSupportedException_CollectionIsReadOnly();
public void Add(T jsonNode) => ThrowHelper.ThrowNotSupportedException_CollectionIsReadOnly();

public void Clear() => ThrowHelper.ThrowNotSupportedException_CollectionIsReadOnly();

public bool Contains(T? jsonNode) => _parent.ContainsValue(jsonNode);
public bool Contains(T jsonNode) => _parent.ContainsValue(jsonNode);

public void CopyTo(T?[] nodeArray, int index)
public void CopyTo(T[] nodeArray, int index)
{
if (index < 0)
{
ThrowHelper.ThrowArgumentOutOfRangeException_ArrayIndexNegative(nameof(index));
}

foreach (KeyValuePair<string, T?> item in _parent)
foreach (KeyValuePair<string, T> item in _parent)
{
if (index >= nodeArray.Length)
{
Expand All @@ -60,15 +60,15 @@ public void CopyTo(T?[] nodeArray, int index)
}
}

public IEnumerator<T?> GetEnumerator()
public IEnumerator<T> GetEnumerator()
{
foreach (KeyValuePair<string, T?> item in _parent)
foreach (KeyValuePair<string, T> item in _parent)
{
yield return item.Value;
}
}

bool ICollection<T?>.Remove(T? node) => throw ThrowHelper.GetNotSupportedException_CollectionIsReadOnly();
bool ICollection<T>.Remove(T node) => throw ThrowHelper.GetNotSupportedException_CollectionIsReadOnly();
}
}
}
Loading