Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 256d650

Browse files
committed
Merge pull request #2133 from Clockwork-Muse/PLINQ_Other
System.Linq.Parallel - Other cleanup
2 parents 17856ab + 1c3ecb3 commit 256d650

16 files changed

+663
-859
lines changed

src/System.Linq.Parallel/tests/Combinatorial/SourcesAndOperators.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@ private static IEnumerable<LabeledOperation> BinaryOperations(LabeledOperation o
206206
yield return Label("Join-Right:" + label, (start, count, source) => source(0, count).Join(other(start, count), x => x, y => y - start, (x, y) => x + start, new ModularCongruenceComparer(count)));
207207
yield return Label("Join-Left:" + label, (start, count, source) => other(0, count).Join(source(start, count), x => x, y => y - start, (x, y) => x + start, new ModularCongruenceComparer(count)));
208208

209-
yield return Label("Union-Right:" + label, (start, count, source) => source(start, count * 3 / 4).Union(other(start + count / 2, count / 2 + count % 2)));
210-
yield return Label("Union-Left:" + label, (start, count, source) => other(start, count * 3 / 4).Union(source(start + count / 2, count / 2 + count % 2)));
209+
yield return Label("Union-Right:" + label, (start, count, source) => source(start, count * 3 / 4).Union(other(start + count / 2, count / 2 + count % 2), new ModularCongruenceComparer(count)));
210+
yield return Label("Union-Left:" + label, (start, count, source) => other(start, count * 3 / 4).Union(source(start + count / 2, count / 2 + count % 2), new ModularCongruenceComparer(count)));
211211

212212
// When both sources are unordered any element can be matched to any other, so a different check is required.
213213
yield return Label("Zip-Unordered-Right:" + label, (start, count, source) => source(0, count).Zip(other(start * 2, count), (x, y) => x + start));

src/System.Linq.Parallel/tests/ExceptionAndParallelEnumerableExceptionTests.cs

Lines changed: 0 additions & 59 deletions
This file was deleted.

src/System.Linq.Parallel/tests/ExchangeTests.cs

Lines changed: 144 additions & 128 deletions
Large diffs are not rendered by default.

src/System.Linq.Parallel/tests/Helpers/Comparers.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public int GetHashCode(T obj)
1919
}
2020
}
2121

22-
internal class ModularCongruenceComparer : IEqualityComparer<int>
22+
internal class ModularCongruenceComparer : IEqualityComparer<int>, IComparer<int>
2323
{
2424
private int _mod;
2525

@@ -47,6 +47,11 @@ public int GetHashCode(object obj)
4747
{
4848
return GetHashCode((int)obj);
4949
}
50+
51+
public int Compare(int x, int y)
52+
{
53+
return leastPositiveResidue(x).CompareTo(leastPositiveResidue(y));
54+
}
5055
}
5156

5257
internal class ReverseComparer : IComparer<int>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
7+
namespace Test
8+
{
9+
internal static class Enumerables<T>
10+
{
11+
/// <summary>
12+
/// Get an enumerable that throws an error on the first enumeration.
13+
/// </summary>
14+
/// <returns>An enumerable that throws on the first enumeration.</returns>
15+
public static IEnumerable<T> ThrowOnEnumeration()
16+
{
17+
return ThrowOnEnumeration(1);
18+
}
19+
20+
/// <summary>
21+
/// Get an enumerable that throws an error after the given number of enumerations.
22+
/// </summary>
23+
/// <param name="count">The number of enumerations until the error is thrown.</param>
24+
/// <returns>An enumerable that throws on the given enumeration.</returns>
25+
public static IEnumerable<T> ThrowOnEnumeration(int count)
26+
{
27+
return Enumerable.Range(0, count).Select(i =>
28+
{
29+
if (i == count - 1) throw new DeliberateTestException();
30+
return default(T);
31+
});
32+
}
33+
}
34+
}

src/System.Linq.Parallel/tests/Helpers/UnorderedSources.cs

Lines changed: 87 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ public static class UnorderedSources
1010
{
1111
public const int AdditionalTypeLimit = 1024;
1212

13+
// Get a set of ranges, of each count in `counts`.
14+
// The start of each range is determined by passing the count into the `start` predicate.
1315
private static IEnumerable<object[]> Ranges(Func<int, int> start, IEnumerable<int> counts)
1416
{
1517
foreach (int count in counts)
@@ -22,33 +24,80 @@ private static IEnumerable<object[]> Ranges(Func<int, int> start, IEnumerable<in
2224
}
2325
}
2426

27+
/// <summary>
28+
/// Get a set of ranges, starting at `start`, and running for each count in `counts`.
29+
/// </summary>
30+
/// <param name="start">The starting element of the range.</param>
31+
/// <param name="counts">The sizes of ranges to return.</param>
32+
/// <returns>Entries for test data.
33+
/// The first element is the Labeled{ParallelQuery{int}} range,
34+
/// the second element is the count, and the third is the start.</returns>
2535
public static IEnumerable<object[]> Ranges(int start, IEnumerable<int> counts)
2636
{
2737
foreach (object[] parms in Ranges(x => start, counts)) yield return parms;
2838
}
2939

30-
// Wrapper for attribute calls
40+
/// <summary>
41+
/// Get a set of ranges, starting at 0, and running for each count in `counts`.
42+
/// </summary>
43+
/// <remarks>This version is a wrapper for use from the MemberData attribute.</remarks>
44+
/// <param name="counts">The sizes of ranges to return.</param>
45+
/// <returns>Entries for test data.
46+
/// The first element is the Labeled{ParallelQuery{int}} range,
47+
/// and the second element is the count</returns>
3148
public static IEnumerable<object[]> Ranges(object[] counts)
3249
{
3350
foreach (object[] parms in Ranges(counts.Cast<int>())) yield return parms;
3451
}
3552

53+
/// <summary>
54+
/// Get a set of ranges, starting at `start`, and running for each count in `counts`.
55+
/// </summary>
56+
/// <remarks>This version is a wrapper for use from the MemberData attribute.</remarks>
57+
/// <param name="start">The starting element of the range.</param>
58+
/// <param name="counts">The sizes of ranges to return.</param>
59+
/// <returns>Entries for test data.
60+
/// The first element is the Labeled{ParallelQuery{int}} range,
61+
/// the second element is the count, and the third is the start.</returns>
3662
public static IEnumerable<object[]> Ranges(int start, object[] counts)
3763
{
3864
foreach (object[] parms in Ranges(start, counts.Cast<int>())) yield return parms;
3965
}
4066

67+
/// <summary>
68+
/// Return pairs of ranges, both from 0 to each respective count in `counts`.
69+
/// </summary>
70+
/// <remarks>This version is a wrapper for use from the MemberData attribute.</remarks>
71+
/// <param name="leftCounts">The sizes of left ranges to return.</param>
72+
/// <param name="rightCounts">The sizes of right ranges to return.</param>
73+
/// <returns>Entries for test data.
74+
/// The first element is the left Labeled{ParallelQuery{int}} range, the second element is the left count,
75+
/// the third element is the right Labeled{ParallelQuery{int}} range, and the fourth element is the right count, .</returns>
4176
public static IEnumerable<object[]> BinaryRanges(object[] leftCounts, object[] rightCounts)
4277
{
4378
foreach (object[] parms in BinaryRanges(leftCounts.Cast<int>(), rightCounts.Cast<int>())) yield return parms;
4479
}
4580

46-
// Simple labeled-range source - just return a set of ranges from 0 to each of the counts.
81+
/// <summary>
82+
/// Get a set of ranges, starting at 0, and running for each count in `counts`.
83+
/// </summary>
84+
/// <param name="counts">The sizes of ranges to return.</param>
85+
/// <returns>Entries for test data.
86+
/// The first element is the Labeled{ParallelQuery{int}} range,
87+
/// and the second element is the count</returns>
4788
public static IEnumerable<object[]> Ranges(IEnumerable<int> counts)
4889
{
4990
foreach (object[] parms in Ranges(x => 0, counts)) yield return parms.Take(2).ToArray();
5091
}
5192

93+
/// <summary>
94+
/// Return pairs of ranges, both from 0 to each respective count in `counts`.
95+
/// </summary>
96+
/// <param name="leftCounts">The sizes of left ranges to return.</param>
97+
/// <param name="rightCounts">The sizes of right ranges to return.</param>
98+
/// <returns>Entries for test data.
99+
/// The first element is the left Labeled{ParallelQuery{int}} range, the second element is the left count,
100+
/// the third element is the right Labeled{ParallelQuery{int}} range, and the fourth element is the right count.</returns>
52101
public static IEnumerable<object[]> BinaryRanges(IEnumerable<int> leftCounts, IEnumerable<int> rightCounts)
53102
{
54103
foreach (object[] left in Ranges(leftCounts))
@@ -60,6 +109,16 @@ public static IEnumerable<object[]> BinaryRanges(IEnumerable<int> leftCounts, IE
60109
}
61110
}
62111

112+
/// <summary>
113+
/// Return pairs of ranges, for each respective count in `counts`.
114+
/// </summary>
115+
/// <param name="leftCounts">The sizes of left ranges to return.</param>
116+
/// <param name="rightStart">A predicate to determine the start of the right range, by passing the left and right range size.</param>
117+
/// <param name="rightCounts">The sizes of right ranges to return.</param>
118+
/// <returns>Entries for test data.
119+
/// The first element is the left Labeled{ParallelQuery{int}} range, the second element is the left count,
120+
/// the third element is the right Labeled{ParallelQuery{int}} range, the fourth element is the right count,
121+
/// and the fifth is the right start..</returns>
63122
public static IEnumerable<object[]> BinaryRanges(IEnumerable<int> leftCounts, Func<int, int, int> rightStart, IEnumerable<int> rightCounts)
64123
{
65124
foreach (object[] left in Ranges(leftCounts))
@@ -71,8 +130,17 @@ public static IEnumerable<object[]> BinaryRanges(IEnumerable<int> leftCounts, Fu
71130
}
72131
}
73132

74-
// Allows for a set of output modifiers to be passed.
75-
// This is useful for things like showing an average (via the use of `x => (double)SumRange(0, x) / x`)
133+
/// <summary>
134+
/// Get a set of ranges, starting at 0, and running for each count in `counts`.
135+
/// </summary>
136+
/// <remarks>
137+
/// This is useful for things like showing an average (via the use of `x => (double)SumRange(0, x) / x`)
138+
/// </remarks>
139+
/// <param name="counts">The sizes of ranges to return.</param>
140+
/// <param name="modifiers">A set of modifiers to return as additional parameters.</param>
141+
/// <returns>Entries for test data.
142+
/// The first element is the Labeled{ParallelQuery{int}} range,
143+
/// the second element is the count, and one additional element for each modifier.</returns>
76144
public static IEnumerable<object[]> Ranges<T>(IEnumerable<int> counts, params Func<int, T>[] modifiers)
77145
{
78146
if (modifiers == null || !modifiers.Any())
@@ -89,10 +157,19 @@ public static IEnumerable<object[]> Ranges<T>(IEnumerable<int> counts, params Fu
89157
}
90158
}
91159

92-
// For each count, each modifier has multiple outputs.
93-
// This is useful for things like dealing with `Max(predicate)`,
94-
// allowing multiple predicate values for the same source count to be tested.
95-
// The number of variations is equal to the longest inner enumeration (all others will cycle).
160+
/// <summary>
161+
/// Get a set of ranges, starting at 0, and running for each count in `counts`.
162+
/// </summary>
163+
/// <remarks>
164+
/// This is useful for things like dealing with `Max(predicate)`,
165+
/// allowing multiple predicate values for the same source count to be tested.
166+
/// The number of variations is equal to the longest modifier enumeration (all others will cycle).
167+
/// </remarks>
168+
/// <param name="counts">The sizes of ranges to return.</param>
169+
/// <param name="modifiers">A set of modifiers to return as additional parameters.</param>
170+
/// <returns>Entries for test data.
171+
/// The first element is the Labeled{ParallelQuery{int}} range,
172+
/// the second element is the count, and one additional element for each modifier.</returns>
96173
public static IEnumerable<object[]> Ranges<T>(IEnumerable<int> counts, params Func<int, IEnumerable<T>>[] modifiers)
97174
{
98175
if (modifiers == null || !modifiers.Any())
@@ -119,11 +196,11 @@ private static IEnumerable<Labeled<ParallelQuery<int>>> LabeledRanges(int start,
119196
yield return Labeled.Label("Enumerable.Range", Enumerable.Range(start, count).AsParallel());
120197
int[] rangeArray = GetRangeArray(start, count);
121198
yield return Labeled.Label("Array", rangeArray.AsParallel());
199+
IList<int> rangeList = rangeArray.ToList();
200+
yield return Labeled.Label("List", rangeList.AsParallel());
122201
if (count < AdditionalTypeLimit + 1)
123202
{
124203
yield return Labeled.Label("Partitioner", Partitioner.Create(rangeArray).AsParallel());
125-
IList<int> rangeList = rangeArray.ToList();
126-
yield return Labeled.Label("List", rangeList.AsParallel());
127204
yield return Labeled.Label("ReadOnlyCollection", new ReadOnlyCollection<int>(rangeList).AsParallel());
128205
}
129206
}

0 commit comments

Comments
 (0)