public static void Except_Unordered_Distinct(Labeled <ParallelQuery <int> > left, int leftCount, Labeled <ParallelQuery <int> > right, int rightCount, int start, int count) { ParallelQuery <int> leftQuery = left.Item; ParallelQuery <int> rightQuery = right.Item; leftCount = Math.Min(DuplicateFactor * 2, leftCount); rightCount = Math.Min(DuplicateFactor, (rightCount + 1) / 2); int expectedCount = Math.Max(0, leftCount - rightCount); IntegerRangeSet seen = new IntegerRangeSet(leftCount - expectedCount, expectedCount); foreach (int i in leftQuery.Except(rightQuery.Select(x => Math.Abs(x) % DuplicateFactor), new ModularCongruenceComparer(DuplicateFactor * 2))) { seen.Add(i % (DuplicateFactor * 2)); } seen.AssertComplete(); }
public static void SelectMany_Indexed_Unordered_ResultSelector(int count, Labeled <Func <int, int, IEnumerable <int> > > expander, int expansion) { // For unordered collections, which element is at which index isn't actually guaranteed, but an effect of the implementation. // If this test starts failing it should be updated, and possibly mentioned in release notes. Func <int, int, IEnumerable <int> > expand = expander.Item; IntegerRangeSet seen = new IntegerRangeSet(0, count * expansion); foreach (var pOuter in UnorderedSources.Default(count).SelectMany((x, index) => expand(x, expansion).Select(y => KeyValuePair.Create(index, y)), (original, expanded) => KeyValuePair.Create(original, expanded))) { var pInner = pOuter.Value; Assert.Equal(pOuter.Key, pInner.Key); seen.Add(pInner.Value); Assert.Equal(pOuter.Key, pInner.Value / expansion); } seen.AssertComplete(); }
public static void Zip_Unordered_NotPipelined(int leftCount, int rightCount) { ParallelQuery <int> leftQuery = UnorderedSources.Default(leftCount); ParallelQuery <int> rightQuery = UnorderedSources.Default(leftCount, rightCount); IntegerRangeSet seen = new IntegerRangeSet(0, Math.Min(leftCount, rightCount)); Assert.All(leftQuery.Zip(rightQuery, (x, y) => KeyValuePair.Create(x, y)).ToList(), pair => { // For unordered collections the pairing isn't actually guaranteed, but an effect of the implementation. // If this test starts failing it should be updated, and possibly mentioned in release notes. Assert.Equal(pair.Key + leftCount, pair.Value); seen.Add(pair.Key); }); seen.AssertComplete(); }
public static void GroupBy_Unordered_ElementSelector_NotPipelined(Labeled <ParallelQuery <int> > labeled, int count) { ParallelQuery <int> query = labeled.Item; IntegerRangeSet groupsSeen = new IntegerRangeSet(0, Math.Min(count, GroupFactor)); foreach (IGrouping <int, int> group in query.GroupBy(x => x % GroupFactor, y => - y).ToList()) { groupsSeen.Add(group.Key); int expected = 1 + (count - (group.Key + 1)) / GroupFactor; IntegerRangeSet elementsSeen = new IntegerRangeSet(1 - expected, expected); Assert.All(group, x => { Assert.Equal(group.Key, -x % GroupFactor); elementsSeen.Add(x / GroupFactor); }); elementsSeen.AssertComplete(); } groupsSeen.AssertComplete(); }
public static void Intersect_Unordered(Labeled <Operation> operation) { Action <Operation, Operation> intersect = (left, right) => { IntegerRangeSet seen = new IntegerRangeSet(DefaultStart, DefaultSize); ParallelQuery <int> query = left(DefaultStart - DefaultSize / 2, DefaultSize + DefaultSize / 2, DefaultSource) .Intersect(right(DefaultStart, DefaultSize + DefaultSize / 2, DefaultSource)); foreach (int i in query) { seen.Add(i); } seen.AssertComplete(); }; intersect(operation.Item, DefaultSource); intersect(DefaultSource, operation.Item); }
public static void Zip_Unordered(Labeled <Operation> operation) { Action <Operation, Operation> zip = (left, right) => { IntegerRangeSet seen = new IntegerRangeSet(DefaultStart, DefaultSize); ParallelQuery <int> query = left(DefaultStart, DefaultSize, DefaultSource) .Zip(right(0, DefaultSize, DefaultSource), (x, y) => x); foreach (int i in query) { seen.Add(i); } seen.AssertComplete(); }; zip(operation.Item, DefaultSource); zip(DefaultSource, operation.Item); }
public static void ToLookup_DuplicateKeys_ElementSelector(Labeled <ParallelQuery <int> > labeled, int count) { ParallelQuery <int> query = labeled.Item; IntegerRangeSet seenOuter = new IntegerRangeSet(0, Math.Min(count, 2)); ILookup <int, int> lookup = query.ToLookup(x => x % 2, y => - y); Assert.All(lookup, group => { seenOuter.Add(group.Key); IntegerRangeSet seenInner = new IntegerRangeSet(0, (count + ((1 + group.Key) % 2)) / 2); Assert.All(group, y => { Assert.Equal(group.Key, -y % 2); seenInner.Add(-y / 2); }); seenInner.AssertComplete(); }); seenOuter.AssertComplete(); Assert.Empty(lookup[-1]); }
public static void Union_Unordered_Distinct(int leftCount, int rightCount) { ParallelQuery <int> leftQuery = UnorderedSources.Default(leftCount); ParallelQuery <int> rightQuery = UnorderedSources.Default(leftCount, rightCount); leftCount = Math.Min(DuplicateFactor, leftCount); rightCount = Math.Min(DuplicateFactor, rightCount); int offset = leftCount - Math.Min(leftCount, rightCount) / 2; int expectedCount = Math.Max(leftCount, rightCount) + (Math.Min(leftCount, rightCount) + 1) / 2; IntegerRangeSet seen = new IntegerRangeSet(0, expectedCount); foreach (int i in leftQuery.Select(x => x % DuplicateFactor).Union(rightQuery.Select(x => (x - leftCount) % DuplicateFactor + offset), new ModularCongruenceComparer(DuplicateFactor + DuplicateFactor / 2))) { seen.Add(i); } seen.AssertComplete(); }
public static void Union_Unordered(Labeled <Operation> operation) { Action <Operation, Operation> union = (left, right) => { IntegerRangeSet seen = new IntegerRangeSet(DefaultStart, DefaultSize); ParallelQuery <int> query = left(DefaultStart, DefaultSize * 3 / 4, DefaultSource) .Union(right(DefaultStart + DefaultSize / 2, DefaultSize / 2, DefaultSource)); foreach (int i in query) { seen.Add(i); } seen.AssertComplete(); }; union(operation.Item, DefaultSource); union(DefaultSource, operation.Item); }
public static void Join_Unordered_NotPipelined(Labeled <Operation> source, Labeled <Operation> operation) { Action <Operation, Operation> join = (left, right) => { IntegerRangeSet seen = new IntegerRangeSet(DefaultStart, DefaultSize); ParallelQuery <KeyValuePair <int, int> > query = left(DefaultStart / GroupFactor, DefaultSize / GroupFactor, DefaultSource) .Join(right(DefaultStart, DefaultSize, DefaultSource), x => x, y => y / GroupFactor, (x, y) => new KeyValuePair <int, int>(x, y)); foreach (KeyValuePair <int, int> p in query.ToList()) { Assert.Equal(p.Key, p.Value / GroupFactor); seen.Add(p.Value); } seen.AssertComplete(); }; join(operation.Item, DefaultSource); join(DefaultSource, operation.Item); }
public static void SelectMany_Indexed_Unordered_ResultSelector_NotPipelined(Labeled <ParallelQuery <int> > labeled, int count, Labeled <Func <int, int, IEnumerable <int> > > expander, int expansion) { // For unordered collections, which element is at which index isn't actually guaranteed, but an effect of the implementation. // If this test starts failing it should be updated, and possibly mentioned in release notes. ParallelQuery <int> query = labeled.Item; Func <int, int, IEnumerable <int> > expand = expander.Item; IntegerRangeSet seen = new IntegerRangeSet(0, count * expansion); Assert.All(query.SelectMany((x, index) => expand(x, expansion).Select(y => KeyValuePair.Create(index, y)), (original, expanded) => KeyValuePair.Create(original, expanded)).ToList(), pOuter => { var pInner = pOuter.Value; Assert.Equal(pOuter.Key, pInner.Key); seen.Add(pInner.Value); Assert.Equal(pOuter.Key, pInner.Value / expansion); }); seen.AssertComplete(); }
public static void GroupBy_Unordered_CustomComparator(int count) { IntegerRangeSet groupsSeen = new IntegerRangeSet(0, Math.Min(count, GroupFactor)); foreach (IGrouping <int, int> group in UnorderedSources.Default(count).GroupBy(x => x, new ModularCongruenceComparer(GroupFactor))) { groupsSeen.Add(group.Key % GroupFactor); IntegerRangeSet elementsSeen = new IntegerRangeSet(0, 1 + (count - (group.Key % GroupFactor + 1)) / GroupFactor); foreach (int i in group) { Assert.Equal(group.Key % GroupFactor, i % GroupFactor); elementsSeen.Add(i / GroupFactor); } elementsSeen.AssertComplete(); } groupsSeen.AssertComplete(); }
public static void GroupBy_Unordered(int count) { IntegerRangeSet groupsSeen = new IntegerRangeSet(0, Math.Min(count, GroupFactor)); foreach (IGrouping <int, int> group in UnorderedSources.Default(count).GroupBy(x => x % GroupFactor)) { groupsSeen.Add(group.Key); IntegerRangeSet elementsSeen = new IntegerRangeSet(0, 1 + (count - (group.Key + 1)) / GroupFactor); foreach (int i in group) { Assert.Equal(group.Key, i % GroupFactor); elementsSeen.Add(i / GroupFactor); } elementsSeen.AssertComplete(); } groupsSeen.AssertComplete(); }
public static void GroupJoin_Unordered_NotPipelined(Labeled <Operation> operation) { Action <Operation, Operation> groupJoin = (left, right) => { IntegerRangeSet seenKey = new IntegerRangeSet(DefaultStart / GroupFactor, DefaultSize / GroupFactor); foreach (KeyValuePair <int, IEnumerable <int> > group in left(DefaultStart / GroupFactor, DefaultSize / GroupFactor, DefaultSource) .GroupJoin(right(DefaultStart, DefaultSize, DefaultSource), x => x, y => y / GroupFactor, (k, g) => new KeyValuePair <int, IEnumerable <int> >(k, g)).ToList()) { Assert.True(seenKey.Add(group.Key)); IntegerRangeSet seenElement = new IntegerRangeSet(group.Key * GroupFactor, GroupFactor); Assert.All(group.Value, x => seenElement.Add(x)); seenElement.AssertComplete(); } seenKey.AssertComplete(); }; groupJoin(operation.Item, DefaultSource); groupJoin(DefaultSource, operation.Item); }
public static void GroupBy_Unordered(Labeled <ParallelQuery <int> > labeled, int count) { ParallelQuery <int> query = labeled.Item; IntegerRangeSet groupsSeen = new IntegerRangeSet(0, Math.Min(count, GroupFactor)); foreach (IGrouping <int, int> group in query.GroupBy(x => x % GroupFactor)) { groupsSeen.Add(group.Key); IntegerRangeSet elementsSeen = new IntegerRangeSet(0, 1 + (count - (group.Key + 1)) / GroupFactor); foreach (int i in group) { Assert.Equal(group.Key, i % GroupFactor); elementsSeen.Add(i / GroupFactor); } elementsSeen.AssertComplete(); } groupsSeen.AssertComplete(); }
public static void ToLookup_DuplicateKeys_ElementSelector_CustomComparator(int count) { IntegerRangeSet seenOuter = new IntegerRangeSet(0, Math.Min(count, 2)); ILookup <int, int> lookup = UnorderedSources.Default(count).ToLookup(x => x, y => - y, new ModularCongruenceComparer(2)); Assert.All(lookup, group => { seenOuter.Add(group.Key % 2); IntegerRangeSet seenInner = new IntegerRangeSet(0, (count + ((1 + group.Key) % 2)) / 2); Assert.All(group, y => { Assert.Equal(group.Key % 2, -y % 2); seenInner.Add(-y / 2); }); seenInner.AssertComplete(); }); seenOuter.AssertComplete(); if (count < 2) { Assert.Empty(lookup[-1]); } }
public static void Union_SecondOrdered_SourceMultiple(ParallelQuery <int> leftQuery, int leftCount, ParallelQuery <int> rightQuery, int rightCount, int count) { IntegerRangeSet seenUnordered = new IntegerRangeSet(0, leftCount); int seen = leftCount; foreach (int i in leftQuery.Union(rightQuery.AsOrdered())) { if (i >= leftCount) { Assert.Equal(seen++, i); } else { seenUnordered.Add(i); } } Assert.Equal(count, seen); seenUnordered.AssertComplete(); }
public static void Join_Unordered_Multiple(Labeled <ParallelQuery <int> > left, int leftCount, Labeled <ParallelQuery <int> > right, int rightCount) { ParallelQuery <int> leftQuery = left.Item; ParallelQuery <int> rightQuery = right.Item; IntegerRangeSet seenOuter = new IntegerRangeSet(0, Math.Min(leftCount, (rightCount + (KeyFactor - 1)) / KeyFactor)); IntegerRangeSet seenInner = new IntegerRangeSet(0, Math.Min(leftCount * KeyFactor, rightCount)); Assert.All(leftQuery.Join(rightQuery, x => x, y => y / KeyFactor, (x, y) => KeyValuePair.Create(x, y)), p => { Assert.Equal(p.Key, p.Value / KeyFactor); seenInner.Add(p.Value); if (p.Value % KeyFactor == 0) { seenOuter.Add(p.Key); } }); seenOuter.AssertComplete(); seenInner.AssertComplete(); }
public static void ToLookup_DuplicateKeys_CustomComparator(Labeled <ParallelQuery <int> > labeled, int count) { ParallelQuery <int> query = labeled.Item; IntegerRangeSet seenOuter = new IntegerRangeSet(0, Math.Min(count, 2)); ILookup <int, int> lookup = query.ToLookup(x => x, new ModularCongruenceComparer(2)); Assert.All(lookup, group => { seenOuter.Add(group.Key % 2); IntegerRangeSet seenInner = new IntegerRangeSet(0, (count + ((1 + group.Key) % 2)) / 2); Assert.All(group, y => { Assert.Equal(group.Key % 2, y % 2); seenInner.Add(y / 2); }); seenInner.AssertComplete(); }); seenOuter.AssertComplete(); if (count < 2) { Assert.Empty(lookup[-1]); } }
public static void GroupJoin_Unordered(int leftCount, int rightCount) { ParallelQuery <int> leftQuery = UnorderedSources.Default(leftCount); ParallelQuery <int> rightQuery = UnorderedSources.Default(rightCount); IntegerRangeSet seen = new IntegerRangeSet(0, leftCount); foreach (var p in leftQuery.GroupJoin(rightQuery, x => x * KeyFactor, y => y, (x, y) => KeyValuePair.Create(x, y))) { seen.Add(p.Key); if (p.Key < (rightCount + (KeyFactor - 1)) / KeyFactor) { Assert.Equal(p.Key * KeyFactor, Assert.Single(p.Value)); } else { Assert.Empty(p.Value); } } seen.AssertComplete(); }
public static void ToDictionary_ElementSelector_UniqueKeys_CustomComparator(int count) { if (count > 2) { AssertThrows.Wrapped <ArgumentException>(() => UnorderedSources.Default(count).ToDictionary(x => x, y => y, new ModularCongruenceComparer(2))); } else if (count == 1 || count == 2) { IntegerRangeSet seen = new IntegerRangeSet(0, count); foreach (KeyValuePair <int, int> entry in UnorderedSources.Default(count).ToDictionary(x => x, y => y, new ModularCongruenceComparer(2))) { seen.Add(entry.Key); Assert.Equal(entry.Key, entry.Value); } seen.AssertComplete(); } else { Assert.Empty(UnorderedSources.Default(count).ToDictionary(x => x, y => y, new ModularCongruenceComparer(2))); } }
public static void Union_SecondOrdered_NotPipelined(Labeled <ParallelQuery <int> > left, int leftCount, Labeled <ParallelQuery <int> > right, int rightCount) { ParallelQuery <int> leftQuery = left.Item; ParallelQuery <int> rightQuery = right.Item; IntegerRangeSet seenUnordered = new IntegerRangeSet(0, leftCount); int seen = leftCount; Assert.All(leftQuery.Union(rightQuery).ToList(), x => { if (x >= leftCount) { Assert.Equal(seen++, x); } else { seenUnordered.Add(x); } }); Assert.Equal(leftCount + rightCount, seen); seenUnordered.AssertComplete(); }
public static void Union_SecondOrdered(Labeled <ParallelQuery <int> > left, int leftCount, Labeled <ParallelQuery <int> > right, int rightCount) { ParallelQuery <int> leftQuery = left.Item; ParallelQuery <int> rightQuery = right.Item; IntegerRangeSet seenUnordered = new IntegerRangeSet(0, leftCount); int seen = leftCount; foreach (int i in leftQuery.Union(rightQuery)) { if (i >= leftCount) { Assert.Equal(seen++, i); } else { seenUnordered.Add(i); } } Assert.Equal(leftCount + rightCount, seen); seenUnordered.AssertComplete(); }
public static void GroupJoin_Unordered_NotPipelined(Labeled <ParallelQuery <int> > left, int leftCount, Labeled <ParallelQuery <int> > right, int rightCount) { ParallelQuery <int> leftQuery = left.Item; ParallelQuery <int> rightQuery = right.Item; IntegerRangeSet seen = new IntegerRangeSet(0, leftCount); Assert.All(leftQuery.GroupJoin(rightQuery, x => x * KeyFactor, y => y, (x, y) => KeyValuePair.Create(x, y)).ToList(), p => { seen.Add(p.Key); if (p.Key < (rightCount + (KeyFactor - 1)) / KeyFactor) { Assert.Equal(p.Key * KeyFactor, Assert.Single(p.Value)); } else { Assert.Empty(p.Value); } }); seen.AssertComplete(); }
// GroupJoin doesn't always return elements from the right in order. See Issue #1155 public static void GroupJoin_Multiple(Labeled <ParallelQuery <int> > left, int leftCount, Labeled <ParallelQuery <int> > right, int rightCount) { ParallelQuery <int> leftQuery = left.Item; ParallelQuery <int> rightQuery = right.Item; int seenOuter = 0; Assert.All(leftQuery.GroupJoin(rightQuery, x => x, y => y / KeyFactor, (x, y) => KeyValuePair.Create(x, y)), p => { Assert.Equal(seenOuter++, p.Key); if (p.Key < (rightCount + (KeyFactor - 1)) / KeyFactor) { IntegerRangeSet seenInner = new IntegerRangeSet(p.Key * KeyFactor, Math.Min(rightCount - p.Key * KeyFactor, KeyFactor)); Assert.All(p.Value, y => { Assert.Equal(p.Key, y / KeyFactor); seenInner.Add(y); }); seenInner.AssertComplete(); } else { Assert.Empty(p.Value); } }); Assert.Equal(leftCount, seenOuter); }
public static void GroupJoin_Unordered_Multiple(int leftCount, int rightCount) { ParallelQuery <int> leftQuery = UnorderedSources.Default(leftCount); ParallelQuery <int> rightQuery = UnorderedSources.Default(rightCount); IntegerRangeSet seenOuter = new IntegerRangeSet(0, leftCount); Assert.All(leftQuery.GroupJoin(rightQuery, x => x, y => y / KeyFactor, (x, y) => KeyValuePair.Create(x, y)), p => { seenOuter.Add(p.Key); if (p.Key < (rightCount + (KeyFactor - 1)) / KeyFactor) { IntegerRangeSet seenInner = new IntegerRangeSet(p.Key * KeyFactor, Math.Min(rightCount - p.Key * KeyFactor, KeyFactor)); Assert.All(p.Value, y => { Assert.Equal(p.Key, y / KeyFactor); seenInner.Add(y); }); seenInner.AssertComplete(); } else { Assert.Empty(p.Value); } }); seenOuter.AssertComplete(); }
public static void GroupJoin_Unordered_CustomComparator(int leftCount, int rightCount) { ParallelQuery <int> leftQuery = UnorderedSources.Default(leftCount); ParallelQuery <int> rightQuery = UnorderedSources.Default(rightCount); IntegerRangeSet seenOuter = new IntegerRangeSet(0, leftCount); Assert.All(leftQuery.GroupJoin(rightQuery, x => x, y => y % ElementFactor, (x, y) => KeyValuePair.Create(x, y), new ModularCongruenceComparer(KeyFactor)), p => { seenOuter.Add(p.Key); if (p.Key % KeyFactor < Math.Min(ElementFactor, rightCount)) { IntegerRangeSet seenInner = new IntegerRangeSet(0, (rightCount + (ElementFactor - 1) - p.Key % ElementFactor) / ElementFactor); Assert.All(p.Value, y => { Assert.Equal(p.Key % KeyFactor, y % ElementFactor); seenInner.Add(y / ElementFactor); }); seenInner.AssertComplete(); } else { Assert.Empty(p.Value); } }); seenOuter.AssertComplete(); }
public static void GroupJoin_CustomComparator(Labeled <ParallelQuery <int> > left, int leftCount, Labeled <ParallelQuery <int> > right, int rightCount) { ParallelQuery <int> leftQuery = left.Item; ParallelQuery <int> rightQuery = right.Item; int seenOuter = 0; Assert.All(leftQuery.GroupJoin(rightQuery, x => x, y => y % ElementFactor, (x, y) => KeyValuePair.Create(x, y), new ModularCongruenceComparer(KeyFactor)), p => { Assert.Equal(seenOuter++, p.Key); if (p.Key % KeyFactor < Math.Min(ElementFactor, rightCount)) { IntegerRangeSet seenInner = new IntegerRangeSet(0, (rightCount + (ElementFactor - 1) - p.Key % ElementFactor) / ElementFactor); Assert.All(p.Value, y => { Assert.Equal(p.Key % KeyFactor, y % ElementFactor); seenInner.Add(y / ElementFactor); }); seenInner.AssertComplete(); } else { Assert.Empty(p.Value); } }); Assert.Equal(leftCount, seenOuter); }
// Join doesn't always return items from the right ordered. See Issue #1155 public static void Join_Multiple(Labeled <ParallelQuery <int> > left, int leftCount, Labeled <ParallelQuery <int> > right, int rightCount) { ParallelQuery <int> leftQuery = left.Item; ParallelQuery <int> rightQuery = right.Item; int seenOuter = 0; int previousOuter = -1; IntegerRangeSet seenInner = new IntegerRangeSet(0, 0); Assert.All(leftQuery.Join(rightQuery, x => x, y => y / KeyFactor, (x, y) => KeyValuePair.Create(x, y)), p => { if (p.Key != previousOuter) { Assert.Equal(seenOuter++, p.Key); seenInner.AssertComplete(); seenInner = new IntegerRangeSet(p.Key * KeyFactor, Math.Min(rightCount - p.Key * KeyFactor, KeyFactor)); previousOuter = p.Key; } seenInner.Add(p.Value); Assert.Equal(p.Key, p.Value / KeyFactor); }); Assert.Equal(Math.Min(leftCount, (rightCount + (KeyFactor - 1)) / KeyFactor), seenOuter); seenInner.AssertComplete(); }
public static void ToDictionary_UniqueKeys_CustomComparator(Labeled <ParallelQuery <int> > labeled, int count) { ParallelQuery <int> query = labeled.Item; if (count > 2) { AggregateException e = Assert.Throws <AggregateException>(() => query.ToDictionary(x => x, new ModularCongruenceComparer(2))); Assert.IsType <ArgumentException>(e.InnerException); } else if (count == 1 || count == 2) { IntegerRangeSet seen = new IntegerRangeSet(0, count); foreach (KeyValuePair <int, int> entry in query.ToDictionary(x => x, new ModularCongruenceComparer(2))) { seen.Add(entry.Key); Assert.Equal(entry.Key, entry.Value); } seen.AssertComplete(); } else { Assert.Empty(query.ToDictionary(x => x, new ModularCongruenceComparer(2))); } }