|
|
@@ -121,9 +121,10 @@ namespace System.Linq.Parallel.QueryNodes
|
|
|
IEnumerator<V> eSecond = second.GetEnumerator ();
|
|
|
|
|
|
try {
|
|
|
- while (eFirst.MoveNext ()) {
|
|
|
- if (!eSecond.MoveNext ())
|
|
|
- yield break;
|
|
|
+ bool fstHasCurrent = false, sndHasCurrent = false;
|
|
|
+ Tuple<VSlot<U>, VSlot<V>> kvp;
|
|
|
+
|
|
|
+ while ((fstHasCurrent = eFirst.MoveNext ()) & (sndHasCurrent = eSecond.MoveNext ())) {
|
|
|
|
|
|
U e1 = eFirst.Current;
|
|
|
V e2 = eSecond.Current;
|
|
|
@@ -136,8 +137,6 @@ namespace System.Linq.Parallel.QueryNodes
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- Tuple<VSlot<U>, VSlot<V>> kvp;
|
|
|
-
|
|
|
do {
|
|
|
if (store.TryRemove (key1, out kvp) && kvp.Item2.HasValue) {
|
|
|
yield return resultor (e1, kvp.Item2.Value);
|
|
|
@@ -152,6 +151,32 @@ namespace System.Linq.Parallel.QueryNodes
|
|
|
}
|
|
|
} while (!store.TryAdd (key2, Tuple.Create (new VSlot<U> (), new VSlot<V> (e2))));
|
|
|
}
|
|
|
+ if (fstHasCurrent) {
|
|
|
+ do {
|
|
|
+ U e1 = eFirst.Current;
|
|
|
+ TKey key1 = fKeySelect (e1);
|
|
|
+
|
|
|
+ do {
|
|
|
+ if (store.TryRemove (key1, out kvp) && kvp.Item2.HasValue) {
|
|
|
+ yield return resultor (e1, kvp.Item2.Value);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } while (!store.TryAdd (key1, Tuple.Create (new VSlot<U> (e1), new VSlot<V> ())));
|
|
|
+ } while (eFirst.MoveNext ());
|
|
|
+ }
|
|
|
+ if (sndHasCurrent) {
|
|
|
+ do {
|
|
|
+ V e2 = eSecond.Current;
|
|
|
+ TKey key2 = sKeySelect (e2);
|
|
|
+
|
|
|
+ do {
|
|
|
+ if (store.TryRemove (key2, out kvp) && kvp.Item1.HasValue) {
|
|
|
+ yield return resultor (kvp.Item1.Value, e2);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } while (!store.TryAdd (key2, Tuple.Create (new VSlot<U> (), new VSlot<V> (e2))));
|
|
|
+ } while (eSecond.MoveNext ());
|
|
|
+ }
|
|
|
} finally {
|
|
|
eFirst.Dispose ();
|
|
|
eSecond.Dispose ();
|