Skip to content

Commit

Permalink
Replace LINQ's custom Set with HashSet
Browse files Browse the repository at this point in the history
  • Loading branch information
stephentoub committed Mar 13, 2021
1 parent d39ad7a commit 30e0e5f
Show file tree
Hide file tree
Showing 16 changed files with 64 additions and 413 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<Compile Include="System\Linq\Parallel\Enumerables\QueryAggregationOptions.cs" />
<Compile Include="System\Linq\Parallel\Enumerables\RangeEnumerable.cs" />
<Compile Include="System\Linq\Parallel\Enumerables\RepeatEnumerable.cs" />
<Compile Include="System\Linq\Parallel\JaggedArray.cs" />
<Compile Include="System\Linq\Parallel\Merging\ArrayMergeHelper.cs" />
<Compile Include="System\Linq\Parallel\Merging\AsynchronousChannelMergeEnumerator.cs" />
<Compile Include="System\Linq\Parallel\Merging\DefaultMergeHelper.cs" />
Expand Down Expand Up @@ -123,7 +124,6 @@
<Compile Include="System\Linq\Parallel\Scheduling\Scheduling.cs" />
<Compile Include="System\Linq\Parallel\Scheduling\SpoolingTask.cs" />
<Compile Include="System\Linq\Parallel\Scheduling\SpoolingTaskBase.cs" />
<Compile Include="System\Linq\Parallel\Helpers.cs" />
<Compile Include="System\Linq\Parallel\Utils\CancellableEnumerable.cs" />
<Compile Include="System\Linq\Parallel\Utils\ExceptionAggregator.cs" />
<Compile Include="System\Linq\Parallel\Utils\ExchangeUtilities.cs" />
Expand Down
139 changes: 0 additions & 139 deletions src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Helpers.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.Linq.Parallel
{
internal class JaggedArray<TElement>
{
public static TElement[][] Allocate(int size1, int size2)
{
TElement[][] ret = new TElement[size1][];
for (int i = 0; i < size1; i++)
ret[i] = new TElement[size2];

return ret;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ private class ExceptQueryOperatorEnumerator<TLeftKey> : QueryOperatorEnumerator<
private readonly QueryOperatorEnumerator<Pair<TInputOutput, NoKeyMemoizationRequired>, TLeftKey> _leftSource; // Left data source.
private readonly QueryOperatorEnumerator<Pair<TInputOutput, NoKeyMemoizationRequired>, int> _rightSource; // Right data source.
private readonly IEqualityComparer<TInputOutput>? _comparer; // A comparer used for equality checks/hash-coding.
private Set<TInputOutput>? _hashLookup; // The hash lookup, used to produce the distinct set.
private HashSet<TInputOutput>? _hashLookup; // The hash lookup, used to produce the distinct set.
private readonly CancellationToken _cancellationToken;
private Shared<int>? _outputLoopCount;

Expand Down Expand Up @@ -177,7 +177,7 @@ internal override bool MoveNext([MaybeNullWhen(false), AllowNull] ref TInputOutp
{
_outputLoopCount = new Shared<int>(0);

_hashLookup = new Set<TInputOutput>(_comparer);
_hashLookup = new HashSet<TInputOutput>(_comparer);

Pair<TInputOutput, NoKeyMemoizationRequired> rightElement = default(Pair<TInputOutput, NoKeyMemoizationRequired>);
int rightKeyUnused = default(int);
Expand Down Expand Up @@ -265,7 +265,7 @@ internal override bool MoveNext([MaybeNullWhen(false), AllowNull] ref TInputOutp
// Build the set out of the left data source, if we haven't already.
if (_outputEnumerator == null)
{
Set<TInputOutput> rightLookup = new Set<TInputOutput>(_comparer);
HashSet<TInputOutput> rightLookup = new HashSet<TInputOutput>(_comparer);

Pair<TInputOutput, NoKeyMemoizationRequired> rightElement = default(Pair<TInputOutput, NoKeyMemoizationRequired>);
int rightKeyUnused = default(int);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ private class IntersectQueryOperatorEnumerator<TLeftKey> : QueryOperatorEnumerat
private readonly QueryOperatorEnumerator<Pair<TInputOutput, NoKeyMemoizationRequired>, TLeftKey> _leftSource; // Left data source.
private readonly QueryOperatorEnumerator<Pair<TInputOutput, NoKeyMemoizationRequired>, int> _rightSource; // Right data source.
private readonly IEqualityComparer<TInputOutput>? _comparer; // Comparer to use for equality/hash-coding.
private Set<TInputOutput>? _hashLookup; // The hash lookup, used to produce the intersection.
private HashSet<TInputOutput>? _hashLookup; // The hash lookup, used to produce the intersection.
private readonly CancellationToken _cancellationToken;
private Shared<int>? _outputLoopCount;

Expand Down Expand Up @@ -164,7 +164,7 @@ internal override bool MoveNext([MaybeNullWhen(false), AllowNull] ref TInputOutp
if (_hashLookup == null)
{
_outputLoopCount = new Shared<int>(0);
_hashLookup = new Set<TInputOutput>(_comparer);
_hashLookup = new HashSet<TInputOutput>(_comparer);

Pair<TInputOutput, NoKeyMemoizationRequired> rightElement = default(Pair<TInputOutput, NoKeyMemoizationRequired>);
int rightKeyUnused = default(int);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ private class UnionQueryOperatorEnumerator<TLeftKey, TRightKey> : QueryOperatorE
{
private QueryOperatorEnumerator<Pair<TInputOutput, NoKeyMemoizationRequired>, TLeftKey>? _leftSource; // Left data source.
private QueryOperatorEnumerator<Pair<TInputOutput, NoKeyMemoizationRequired>, TRightKey>? _rightSource; // Right data source.
private Set<TInputOutput>? _hashLookup; // The hash lookup, used to produce the union.
private HashSet<TInputOutput>? _hashLookup; // The hash lookup, used to produce the union.
private readonly CancellationToken _cancellationToken;
private Shared<int>? _outputLoopCount;
private readonly IEqualityComparer<TInputOutput>? _comparer;
Expand Down Expand Up @@ -216,7 +216,7 @@ internal override bool MoveNext([MaybeNullWhen(false), AllowNull] ref TInputOutp
{
if (_hashLookup == null)
{
_hashLookup = new Set<TInputOutput>(_comparer);
_hashLookup = new HashSet<TInputOutput>(_comparer);
_outputLoopCount = new Shared<int>(0);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ internal override bool LimitsParallelism
private class DistinctQueryOperatorEnumerator<TKey> : QueryOperatorEnumerator<TInputOutput, int>
{
private readonly QueryOperatorEnumerator<Pair<TInputOutput, NoKeyMemoizationRequired>, TKey> _source; // The data source.
private readonly Set<TInputOutput> _hashLookup; // The hash lookup, used to produce the distinct set.
private readonly HashSet<TInputOutput> _hashLookup; // The hash lookup, used to produce the distinct set.
private readonly CancellationToken _cancellationToken;
private Shared<int>? _outputLoopCount; // Allocated in MoveNext to avoid false sharing.

Expand All @@ -133,7 +133,7 @@ internal DistinctQueryOperatorEnumerator(
{
Debug.Assert(source != null);
_source = source;
_hashLookup = new Set<TInputOutput>(comparer);
_hashLookup = new HashSet<TInputOutput>(comparer);
_cancellationToken = cancellationToken;
}

Expand Down
1 change: 0 additions & 1 deletion src/libraries/System.Linq/src/System.Linq.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@
<Compile Include="System\Linq\Select.cs" />
<Compile Include="System\Linq\SelectMany.cs" />
<Compile Include="System\Linq\SequenceEqual.cs" />
<Compile Include="System\Linq\Set.cs" />
<Compile Include="System\Linq\Single.cs" />
<Compile Include="System\Linq\SingleLinkedNode.cs" />
<Compile Include="System\Linq\Skip.cs" />
Expand Down
13 changes: 3 additions & 10 deletions src/libraries/System.Linq/src/System/Linq/Distinct.SpeedOpt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,11 @@ public static partial class Enumerable
{
private sealed partial class DistinctIterator<TSource> : IIListProvider<TSource>
{
private Set<TSource> FillSet()
{
var set = new Set<TSource>(_comparer);
set.UnionWith(_source);
return set;
}
public TSource[] ToArray() => Enumerable.ToArray(new HashSet<TSource>(_source, _comparer));

public TSource[] ToArray() => FillSet().ToArray();
public List<TSource> ToList() => Enumerable.ToList(new HashSet<TSource>(_source, _comparer));

public List<TSource> ToList() => FillSet().ToList();

public int GetCount(bool onlyIfCheap) => onlyIfCheap ? -1 : FillSet().Count;
public int GetCount(bool onlyIfCheap) => onlyIfCheap ? -1 : new HashSet<TSource>(_source, _comparer).Count;
}
}
}
4 changes: 2 additions & 2 deletions src/libraries/System.Linq/src/System/Linq/Distinct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ private sealed partial class DistinctIterator<TSource> : Iterator<TSource>
{
private readonly IEnumerable<TSource> _source;
private readonly IEqualityComparer<TSource>? _comparer;
private Set<TSource>? _set;
private HashSet<TSource>? _set;
private IEnumerator<TSource>? _enumerator;

public DistinctIterator(IEnumerable<TSource> source, IEqualityComparer<TSource>? comparer)
Expand All @@ -53,7 +53,7 @@ public override bool MoveNext()
}

TSource element = _enumerator.Current;
_set = new Set<TSource>(_comparer);
_set = new HashSet<TSource>(DefaultInternalSetCapacity, _comparer);
_set.Add(element);
_current = element;
_state = 2;
Expand Down
3 changes: 1 addition & 2 deletions src/libraries/System.Linq/src/System/Linq/Except.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> fir

private static IEnumerable<TSource> ExceptIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource>? comparer)
{
Set<TSource> set = new Set<TSource>(comparer);
set.UnionWith(second);
var set = new HashSet<TSource>(second, comparer);

foreach (TSource element in first)
{
Expand Down
3 changes: 1 addition & 2 deletions src/libraries/System.Linq/src/System/Linq/Intersect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ public static IEnumerable<TSource> Intersect<TSource>(this IEnumerable<TSource>

private static IEnumerable<TSource> IntersectIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource>? comparer)
{
Set<TSource> set = new Set<TSource>(comparer);
set.UnionWith(second);
var set = new HashSet<TSource>(second, comparer);

foreach (TSource element in first)
{
Expand Down
Loading

0 comments on commit 30e0e5f

Please sign in to comment.