Example #1
0
        public static void GroupJoin_NotPipelined(Labeled <ParallelQuery <int> > left, int leftCount, Labeled <ParallelQuery <int> > right, int rightCount)
        {
            ParallelQuery <int> leftQuery  = left.Item;
            ParallelQuery <int> rightQuery = right.Item;
            int seen = 0;

            Assert.All(leftQuery.GroupJoin(rightQuery, x => x * KeyFactor, y => y, (x, y) => KeyValuePair.Create(x, y)).ToList(),
                       p =>
            {
                Assert.Equal(seen++, p.Key);
                if (p.Key < (rightCount + (KeyFactor - 1)) / KeyFactor)
                {
                    Assert.Equal(p.Key * KeyFactor, Assert.Single(p.Value));
                }
                else
                {
                    Assert.Empty(p.Value);
                }
            });
            Assert.Equal(leftCount, seen);
        }
Example #2
0
        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();
        }
Example #3
0
        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);
        }
Example #4
0
        // 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_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_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();
        }
        private static void RunAllTests(
            TestTracker result, ParallelQuery <int> q, bool orderPreserved,
            string leftOpName, bool leftOrderDefined)
        {
            LogTestRun(leftOpName, "All1", orderPreserved);
            result.MustEqual(
                q.All(i => i > 100),
                q.ToArray().Any(i => i > 100));

            LogTestRun(leftOpName, "All2", orderPreserved);
            result.MustEqual(
                q.All(i => i == 75),
                q.ToArray().All(i => i == 75));

            LogTestRun(leftOpName, "Any1", orderPreserved);
            result.MustEqual(
                q.Any(i => i > 100),
                q.ToArray().Any(i => i > 100));

            LogTestRun(leftOpName, "Any2", orderPreserved);
            result.MustEqual(
                q.Any(i => i == 75),
                q.ToArray().Any(i => i == 75));

            LogTestRun(leftOpName, "Concat", orderPreserved);
            result.MustSequenceEqual(
                q.Concat(q).Concat(new int[] { 1, 2, 3 }.AsParallel()),
                q.Reverse().Reverse().ToArray().Concat(q.Reverse().Reverse()).Concat(new int[] { 1, 2, 3 }),
                leftOrderDefined && orderPreserved);

            LogTestRun(leftOpName, "DefaultIfEmpty", orderPreserved);
            result.MustSequenceEqual(
                q.DefaultIfEmpty(),
                q.ToArray().DefaultIfEmpty(), orderPreserved && leftOrderDefined);

            LogTestRun(leftOpName, "ElementAt", orderPreserved);
            IEnumerable <int> q2 = q.ToArray();
            int        count1 = q.Count(), count2 = q2.Count();
            List <int> list1 = new List <int>();
            List <int> list2 = new List <int>();

            for (int i = 0; i < count1; i++)
            {
                list1.Add(q.ElementAt(i));
            }
            for (int i = 0; i < count2; i++)
            {
                list2.Add(q2.ElementAt(i));
            }
            result.MustSequenceEqual(list1, list2, leftOrderDefined);

            LogTestRun(leftOpName, "Except", orderPreserved);
            result.MustSequenceEqual(
                q.Except(Enumerable.Range(90, 50).AsParallel()),
                q.ToArray().Except(Enumerable.Range(90, 50)),
                false);

            LogTestRun(leftOpName, "First", orderPreserved);
            CheckFirstOrLast(
                result,
                q.First(),
                q.ToArray().First(),
                leftOrderDefined);

            LogTestRun(leftOpName, "GroupBy", orderPreserved);
            result.MustGroupByEqual(
                q.GroupBy(i => i % 5, (i, e) => new Pair <int, IEnumerable <int> >(i, e)),
                q.ToArray().GroupBy(i => i % 5, (i, e) => new Pair <int, IEnumerable <int> >(i, e)));

            LogTestRun(leftOpName, "GroupJoin", orderPreserved);
            result.MustSequenceEqual(
                q.GroupJoin(q, i => i, i => i, (i, e) => e.FirstOrDefault()),
                q.ToArray().GroupJoin(q.ToArray(), i => i, i => i, (i, e) => e.FirstOrDefault()),
                false);

            LogTestRun(leftOpName, "Intersect", orderPreserved);
            result.MustSequenceEqual(
                q.Intersect(Enumerable.Range(90, 50).AsParallel()),
                q.ToArray().Intersect(Enumerable.Range(90, 50)),
                false);

            LogTestRun(leftOpName, "Join1", orderPreserved);
            result.MustSequenceEqual(
                q.Join((new int[] { 1, 1, 2, 3, 3 }).AsParallel(), i => i, i => i, (i, j) => i + j),
                q.ToArray().Join(new int[] { 1, 1, 2, 3, 3 }, i => i, i => i, (i, j) => i + j),
                false);

            LogTestRun(leftOpName, "Join2", orderPreserved);
            result.MustSequenceEqual(
                q.Join((new int[] { 1, 1, 100, 3, 3 }).AsParallel(), i => new String('a', i), i => new String('a', i), (i, j) => i + j),
                q.ToArray().Join(new int[] { 1, 1, 100, 3, 3 }, i => new String('a', i), i => new String('a', i), (i, j) => i + j),
                false);

            LogTestRun(leftOpName, "Last", orderPreserved);
            CheckFirstOrLast(
                result,
                q.Last(),
                q.ToArray().Last(),
                leftOrderDefined);

            LogTestRun(leftOpName, "Min", orderPreserved);
            CheckFirstOrLast(
                result,
                q.Min(),
                q.ToArray().Min(),
                leftOrderDefined);

            LogTestRun(leftOpName, "Max", orderPreserved);
            CheckFirstOrLast(
                result,
                q.Min(),
                q.ToArray().Min(),
                leftOrderDefined);

            LogTestRun(leftOpName, "OrderBy-ThenBy", orderPreserved);
            result.MustSequenceEqual(
                q.Concat(q).OrderBy(i => i % 5).ThenBy(i => - i),
                q.ToArray().Concat(q).OrderBy(i => i % 5).ThenBy(i => - i),
                true);

            LogTestRun(leftOpName, "OrderByDescending-ThenByDescending", orderPreserved);
            result.MustSequenceEqual(
                q.Concat(q).OrderByDescending(i => i % 5).ThenByDescending(i => - i),
                q.ToArray().Concat(q).OrderByDescending(i => i % 5).ThenByDescending(i => - i),
                true);

            LogTestRun(leftOpName, "Reverse", orderPreserved);
            result.MustSequenceEqual(
                q.Concat(q).Reverse(),
                q.ToArray().Concat(q).Reverse(),
                orderPreserved && leftOrderDefined);

            LogTestRun(leftOpName, "Select", orderPreserved);
            result.MustSequenceEqual(
                q.Select(i => 5 * i - 17),
                q.ToArray().Select(i => 5 * i - 17),
                orderPreserved && leftOrderDefined);

            LogTestRun(leftOpName, "SelectMany", orderPreserved);
            result.MustSequenceEqual(
                q.SelectMany(i => new int[] { 1, 2, 3 }, (i, j) => i + 100 * j),
                q.ToArray().SelectMany(i => new int[] { 1, 2, 3 }, (i, j) => i + 100 * j),
                false);

            LogTestRun(leftOpName, "SequenceEqual", orderPreserved);
            if (orderPreserved && leftOrderDefined)
            {
                result.MustEqual(q.SequenceEqual(q), true);
            }
            else
            {
                // We don't check the return value as it can be either true or false
                q.SequenceEqual(q);
            }

            LogTestRun(leftOpName, "Skip", orderPreserved);
            CheckTakeSkip(
                result,
                q.Skip(10),
                q.ToArray().Skip(10),
                leftOrderDefined && orderPreserved);

            LogTestRun(leftOpName, "SkipWhile", orderPreserved);
            CheckTakeSkip(
                result,
                q.SkipWhile(i => i < 30),
                q.ToArray().SkipWhile(i => i < 30),
                leftOrderDefined && orderPreserved);

            LogTestRun(leftOpName, "SkipWhileIndexed", orderPreserved);
            CheckTakeSkip(
                result,
                q.SkipWhile((i, j) => j < 30),
                q.ToArray().SkipWhile((i, j) => j < 30),
                leftOrderDefined && orderPreserved);

            LogTestRun(leftOpName, "Take", orderPreserved);
            CheckTakeSkip(
                result,
                q.Take(10),
                q.ToArray().Take(10),
                leftOrderDefined && orderPreserved);

            LogTestRun(leftOpName, "TakeWhile", orderPreserved);
            CheckTakeSkip(
                result,
                q.TakeWhile(i => i < 30),
                q.ToArray().TakeWhile(i => i < 30),
                leftOrderDefined && orderPreserved);

            LogTestRun(leftOpName, "TakeWhileIndexed", orderPreserved);
            CheckTakeSkip(
                result,
                q.TakeWhile((i, j) => j < 30),
                q.ToArray().TakeWhile((i, j) => j < 30),
                leftOrderDefined && orderPreserved);

            LogTestRun(leftOpName, "Union", orderPreserved);
            result.MustSequenceEqual(
                q.Union(Enumerable.Range(90, 50).AsParallel()),
                q.ToArray().Union(Enumerable.Range(90, 50)),
                false);

            LogTestRun(leftOpName, "Where", orderPreserved);
            result.MustSequenceEqual(
                q.Where(i => i < 20 || i > 80),
                q.ToArray().Where(i => i < 20 || i > 80),
                orderPreserved && leftOrderDefined);

            LogTestRun(leftOpName, "Zip", orderPreserved);
            IEnumerable <KeyValuePair <int, int> > zipQ = q.Zip(q, (i, j) => new KeyValuePair <int, int>(i, j));

            result.MustSequenceEqual(
                zipQ.Select(p => p.Key),
                q.Reverse().Reverse().ToArray(),
                orderPreserved && leftOrderDefined);
            result.MustSequenceEqual(
                zipQ.Select(p => p.Value),
                q.Reverse().Reverse().ToArray(),
                orderPreserved && leftOrderDefined);
        }
        public static void GroupJoin_CustomComparator_LeftWithOrderingColisions(Labeled <ParallelQuery <int> > left, int leftCount, Labeled <ParallelQuery <int> > right, int rightCount)
        {
            ParallelQuery <int> leftQuery  = left.Item.AsUnordered().OrderBy(x => x / KeyFactor);
            ParallelQuery <int> rightQuery = right.Item;
            int seenNonEmpty  = 0;
            int seenEmpty     = 0;
            int seenLeftGroup = 0;
            int seenLeftCount = 0;

            Assert.All(leftQuery.GroupJoin(rightQuery, x => x, y => y % ElementFactor, (x, y) => KeyValuePair.Create(x, y), new ModularCongruenceComparer(KeyFactor)),
                       p =>
            {
                seenLeftCount++;

                if (p.Key / KeyFactor > seenLeftGroup)
                {
                    seenLeftGroup++;

                    try
                    {
                        Assert.Equal(KeyFactor, seenEmpty + seenNonEmpty);
                    }
                    finally
                    {
                        seenEmpty    = 0;
                        seenNonEmpty = 0;
                    }
                }
                Assert.Equal(seenLeftGroup, p.Key / KeyFactor);

                if (p.Key % KeyFactor < Math.Min(ElementFactor, rightCount))
                {
                    try
                    {
                        Assert.Equal((seenLeftGroup * KeyFactor) + seenNonEmpty, p.Key);
                    }
                    finally
                    {
                        seenNonEmpty++;
                    }

                    int expectedInner  = p.Key % ElementFactor;
                    int seenInnerCount = 0;
                    Assert.All(p.Value, y =>
                    {
                        seenInnerCount++;
                        Assert.Equal(p.Key % KeyFactor, y % ElementFactor);
                        try
                        {
                            Assert.Equal(expectedInner, y);
                        }
                        finally
                        {
                            expectedInner += ElementFactor;
                        }
                    });
                    Assert.Equal((rightCount / ElementFactor) + (((rightCount % ElementFactor) > (p.Key % KeyFactor)) ? 1 : 0), seenInnerCount);
                }
                else
                {
                    seenEmpty++;

                    Assert.Equal(0, seenNonEmpty);
                    Assert.Empty(p.Value);
                }
            });
            Assert.Equal(leftCount, seenLeftCount);
        }
Example #9
0
        public static ParallelQuery <TResult> LeftJoin <TOuter, TInner, TKey, TResult>(this ParallelQuery <TOuter> outer, ParallelQuery <TInner> inner, Func <TOuter, TKey> outerKeySelector, Func <TInner, TKey> innerKeySelector, Func <TOuter, TInner, TResult> resultSelector)
        {
            ParallelQuery <TResult> results = outer.GroupJoin(inner, outerKeySelector, innerKeySelector, (x, y) => new { Outer = x, Inner = y.SingleOrDefault() }).Select(x => resultSelector(x.Outer, x.Inner));

            return(results);
        }
Example #10
0
        public static ParallelQuery <TOuter> NotJoin <TOuter, TInner, TKey>(this ParallelQuery <TOuter> outer, ParallelQuery <TInner> inner, Func <TOuter, TKey> outerKeySelector, Func <TInner, TKey> innerKeySelector)
        {
            ParallelQuery <TOuter> results = outer.GroupJoin(inner, outerKeySelector, innerKeySelector, (x, y) => new { Outer = x, Inner = y.Any() }).Where(x => !x.Inner).Select(x => x.Outer);

            return(results);
        }
Example #11
0
 public static void ForEach <TOuter, TInner, TKey>(this ParallelQuery <TOuter> outer, ParallelQuery <TInner> inner, Func <TOuter, TKey> outerKeySelector, Func <TInner, TKey> innerKeySelector, Action <TOuter, TInner> resultSelector)
 {
     outer.GroupJoin(inner, outerKeySelector, innerKeySelector, (x, y) => new { Outer = x, Inner = y.SingleOrDefault() }).ForAll(x => resultSelector(x.Outer, x.Inner));
 }