[System.Core] Returns false in SequenceEqual when the two sequences size are different
authorJérémie Laval <jeremie.laval@gmail.com>
Tue, 4 Sep 2012 15:35:57 +0000 (16:35 +0100)
committerJérémie Laval <jeremie.laval@gmail.com>
Tue, 4 Sep 2012 15:36:36 +0000 (16:36 +0100)
mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryZipNode.cs
mcs/class/System.Core/System.Linq/ParallelEnumerable.cs
mcs/class/System.Core/Test/System.Linq/ParallelEnumerableTests.cs

index 62856779801d1a7ccbf60d9cd97be62fa5f17d81..9b9b475ac6807aa71047e8b93ff111d998d485d8 100644 (file)
@@ -43,6 +43,12 @@ namespace System.Linq.Parallel.QueryNodes
                        this.resultSelector = resultSelector;
                }
 
+               // If strict is set to `true', the zip'ing process will throw if sequences length mistmatches
+               public bool Strict {
+                       get;
+                       set;
+               }
+
                internal override IEnumerable<TResult> GetSequential ()
                {
                        IEnumerable<TFirst> first = Parent.GetSequential ();
@@ -71,11 +77,17 @@ namespace System.Linq.Parallel.QueryNodes
 
                        try {
                                while (eFirst.MoveNext ()) {
-                                       if (!eSecond.MoveNext ())
-                                               yield break;
+                                       if (!eSecond.MoveNext ()) {
+                                               if (Strict)
+                                                       throw new QueryZipException ();
+                                               else
+                                                       yield break;
+                                       }
 
                                        yield return resultSelector (eFirst.Current, eSecond.Current);
                                }
+                               if (Strict && eSecond.MoveNext ())
+                                       throw new QueryZipException ();
                        } finally {
                                eFirst.Dispose ();
                                eSecond.Dispose ();
@@ -115,8 +127,12 @@ namespace System.Linq.Parallel.QueryNodes
 
                        try {
                                while (eFirst.MoveNext ()) {
-                                       if (!eSecond.MoveNext ())
-                                               break;
+                                       if (!eSecond.MoveNext ()) {
+                                               if (Strict)
+                                                       throw new QueryZipException ();
+                                               else
+                                                       break;
+                                       }
 
                                        store1[index] = eFirst.Current;
                                        store2[index] = eSecond.Current;
@@ -126,6 +142,8 @@ namespace System.Linq.Parallel.QueryNodes
                                        yield return new KeyValuePair<long, TResult> (store1[index].Key,
                                                                                      resultSelector (store1[index].Value, store2[index].Value));
                                }
+                               if (Strict && eSecond.MoveNext ())
+                                       throw new QueryZipException ();
                        } finally {
                                barrier.RemoveParticipant ();
                                eFirst.Dispose ();
@@ -133,6 +151,10 @@ namespace System.Linq.Parallel.QueryNodes
                        }
                }
        }
+
+       internal class QueryZipException : Exception
+       {
+       }
 }
 
 #endif
index a62fb7da7961f9e2e78c9ac6ab0b149c838e1172..6d9e637b4c9fd04992ffef6b8fdb0f4ef5eed87f 100644 (file)
@@ -552,7 +552,8 @@ namespace System.Linq
                                comparer = EqualityComparer<TSource>.Default;
 
                        var source = new CancellationTokenSource ();
-                       var innerQuery = first.Zip (second, comparer.Equals).WithImplementerToken (source);
+                       var zip = new QueryZipNode<TSource, TSource, bool> (comparer.Equals, first.Node, second.Node) { Strict = true };
+                       var innerQuery = new ParallelQuery<bool> (zip).WithImplementerToken (source);
 
                        bool result = true;
 
@@ -563,6 +564,11 @@ namespace System.Linq
                                                source.Cancel ();
                                        }
                                });
+                       } catch (AggregateException ex) {
+                               if (ex.InnerException is QueryZipException)
+                                       return false;
+                               else
+                                       throw ex;
                        } catch (OperationCanceledException e) {
                                if (e.CancellationToken != source.Token)
                                        throw e;
index 4381fca2025dd2f932f1932ed579da8e0b0a1271..9301f288f94c1605bebe42581b61b6c76fc81d6c 100644 (file)
@@ -890,6 +890,21 @@ namespace MonoTests.System.Linq
                        Assert.IsFalse (data.AsReallyParallel ().All (x => x != 1));
                        Assert.IsTrue (empty.AsReallyParallel ().All (x => false));
                }
+
+               [Test]
+               public void SequenceEqualsTest ()
+               {
+                       var data1 = new int[] { 1, 2, 3 };
+                       var data2 = new int[] { 1, 2, 4 };
+                       var data3 = new int[] { 1, 2, 3, 4 };
+
+                       Assert.IsTrue (data1.AsReallyParallel ().SequenceEqual (data1.AsReallyParallel ()));
+                       Assert.IsTrue (data2.AsReallyParallel ().SequenceEqual (data2.AsReallyParallel ()));
+                       Assert.IsTrue (data3.AsReallyParallel ().SequenceEqual (data3.AsReallyParallel ()));
+                       Assert.IsFalse (data1.AsReallyParallel ().SequenceEqual (data2.AsReallyParallel ()));
+                       Assert.IsFalse (data1.AsReallyParallel ().SequenceEqual (data3.AsReallyParallel ()));
+                       Assert.IsFalse (data2.AsReallyParallel ().SequenceEqual (data3.AsReallyParallel ()));
+               }
        }
 }