1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Collections.Generic; 6 using Xunit; 7 8 namespace System.Linq.Parallel.Tests 9 { 10 public static class DistinctTests 11 { 12 private const int DuplicateFactor = 4; 13 DistinctUnorderedData(int[] counts)14 public static IEnumerable<object[]> DistinctUnorderedData(int[] counts) 15 { 16 foreach (int count in counts) 17 { 18 yield return new object[] { count * DuplicateFactor, count }; 19 } 20 } 21 DistinctData(int[] counts)22 public static IEnumerable<object[]> DistinctData(int[] counts) 23 { 24 foreach (object[] results in Sources.Ranges(counts.Select(x => x * DuplicateFactor).DefaultIfEmpty(Sources.OuterLoopCount))) 25 { 26 yield return new object[] { results[0], ((int)results[1]) / DuplicateFactor }; 27 } 28 } 29 DistinctSourceMultipleData(int[] counts)30 public static IEnumerable<object[]> DistinctSourceMultipleData(int[] counts) 31 { 32 foreach (int count in counts.DefaultIfEmpty(Sources.OuterLoopCount)) 33 { 34 int[] source = Enumerable.Range(0, count * DuplicateFactor).Select(x => x % count).ToArray(); 35 36 yield return new object[] { Labeled.Label("Array", source.AsParallel().AsOrdered()), count }; 37 yield return new object[] { Labeled.Label("List", source.ToList().AsParallel().AsOrdered()), count }; 38 yield return new object[] { Labeled.Label("Enumerable", source.AsEnumerable().AsParallel().AsOrdered()), count }; 39 } 40 } 41 42 // 43 // Distinct 44 // 45 [Theory] 46 [MemberData(nameof(DistinctUnorderedData), new[] { 0, 1, 2, 16 })] Distinct_Unordered(int count, int uniqueCount)47 public static void Distinct_Unordered(int count, int uniqueCount) 48 { 49 IntegerRangeSet seen = new IntegerRangeSet(0, uniqueCount); 50 foreach (int i in UnorderedSources.Default(count).Distinct(new ModularCongruenceComparer(uniqueCount))) 51 { 52 seen.Add(i % uniqueCount); 53 } 54 seen.AssertComplete(); 55 } 56 57 [Fact] 58 [OuterLoop] Distinct_Unordered_Longrunning()59 public static void Distinct_Unordered_Longrunning() 60 { 61 Distinct_Unordered(Sources.OuterLoopCount, Sources.OuterLoopCount / DuplicateFactor); 62 } 63 64 [Theory] 65 [MemberData(nameof(DistinctData), new[] { 0, 1, 2, 16 })] Distinct(Labeled<ParallelQuery<int>> labeled, int count)66 public static void Distinct(Labeled<ParallelQuery<int>> labeled, int count) 67 { 68 ParallelQuery<int> query = labeled.Item; 69 int seen = 0; 70 foreach (int i in query.Distinct(new ModularCongruenceComparer(count))) 71 { 72 Assert.Equal(seen++, i % count); 73 } 74 Assert.Equal(count, seen); 75 } 76 77 [Theory] 78 [OuterLoop] 79 [MemberData(nameof(DistinctData), new int[] { /* Sources.OuterLoopCount */ })] Distinct_Longrunning(Labeled<ParallelQuery<int>> labeled, int count)80 public static void Distinct_Longrunning(Labeled<ParallelQuery<int>> labeled, int count) 81 { 82 Distinct(labeled, count); 83 } 84 85 [Theory] 86 [MemberData(nameof(DistinctUnorderedData), new[] { 0, 1, 2, 16 })] Distinct_Unordered_NotPipelined(int count, int uniqueCount)87 public static void Distinct_Unordered_NotPipelined(int count, int uniqueCount) 88 { 89 IntegerRangeSet seen = new IntegerRangeSet(0, uniqueCount); 90 Assert.All(UnorderedSources.Default(count).Distinct(new ModularCongruenceComparer(uniqueCount)).ToList(), x => seen.Add(x % uniqueCount)); 91 seen.AssertComplete(); 92 } 93 94 [Fact] 95 [OuterLoop] Distinct_Unordered_NotPipelined_Longrunning()96 public static void Distinct_Unordered_NotPipelined_Longrunning() 97 { 98 Distinct_Unordered_NotPipelined(Sources.OuterLoopCount, Sources.OuterLoopCount / DuplicateFactor); 99 } 100 101 [Theory] 102 [MemberData(nameof(DistinctData), new[] { 0, 1, 2, 16 })] Distinct_NotPipelined(Labeled<ParallelQuery<int>> labeled, int count)103 public static void Distinct_NotPipelined(Labeled<ParallelQuery<int>> labeled, int count) 104 { 105 ParallelQuery<int> query = labeled.Item; 106 int seen = 0; 107 Assert.All(query.Distinct(new ModularCongruenceComparer(count)).ToList(), x => Assert.Equal(seen++, x % count)); 108 Assert.Equal(count, seen); 109 } 110 111 [Theory] 112 [OuterLoop] 113 [MemberData(nameof(DistinctData), new int[] { /* Sources.OuterLoopCount */ })] Distinct_NotPiplined_Longrunning(Labeled<ParallelQuery<int>> labeled, int count)114 public static void Distinct_NotPiplined_Longrunning(Labeled<ParallelQuery<int>> labeled, int count) 115 { 116 Distinct_NotPipelined(labeled, count); 117 } 118 119 [Theory] 120 [MemberData(nameof(DistinctSourceMultipleData), new[] { 0, 1, 2, 16 })] Distinct_Unordered_SourceMultiple(Labeled<ParallelQuery<int>> labeled, int count)121 public static void Distinct_Unordered_SourceMultiple(Labeled<ParallelQuery<int>> labeled, int count) 122 { 123 // The difference between this test and the previous, is that it's not possible to 124 // get non-unique results from ParallelEnumerable.Range()... 125 // Those tests either need modification of source (via .Select(x => x / DuplicateFactor) or similar, 126 // or via a comparator that considers some elements equal. 127 IntegerRangeSet seen = new IntegerRangeSet(0, count); 128 Assert.All(labeled.Item.AsUnordered().Distinct(), x => seen.Add(x)); 129 seen.AssertComplete(); 130 } 131 132 [Theory] 133 [OuterLoop] 134 [MemberData(nameof(DistinctSourceMultipleData), new int[] { /* Sources.OuterLoopCount */ })] Distinct_Unordered_SourceMultiple_Longrunning(Labeled<ParallelQuery<int>> labeled, int count)135 public static void Distinct_Unordered_SourceMultiple_Longrunning(Labeled<ParallelQuery<int>> labeled, int count) 136 { 137 Distinct_Unordered_SourceMultiple(labeled, count); 138 } 139 140 [Theory] 141 [MemberData(nameof(DistinctSourceMultipleData), new[] { 0, 1, 2, 16 })] Distinct_SourceMultiple(Labeled<ParallelQuery<int>> labeled, int count)142 public static void Distinct_SourceMultiple(Labeled<ParallelQuery<int>> labeled, int count) 143 { 144 int seen = 0; 145 Assert.All(labeled.Item.Distinct(), x => Assert.Equal(seen++, x)); 146 Assert.Equal(count, seen); 147 } 148 149 [Theory] 150 [OuterLoop] 151 [MemberData(nameof(DistinctSourceMultipleData), new int[] { /* Sources.OuterLoopCount */ })] Distinct_SourceMultiple_Longrunning(Labeled<ParallelQuery<int>> labeled, int count)152 public static void Distinct_SourceMultiple_Longrunning(Labeled<ParallelQuery<int>> labeled, int count) 153 { 154 Distinct_SourceMultiple(labeled, count); 155 } 156 157 [Fact] Distinct_ArgumentNullException()158 public static void Distinct_ArgumentNullException() 159 { 160 AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<int>)null).Distinct()); 161 } 162 } 163 } 164