//--------------------------------------------------------------------------------------- // Walks the two data sources, left and then right, to produce the union. // internal override bool MoveNext(ref TInputOutput currentElement, ref ConcatKey <TLeftKey, TRightKey> currentKey) { Contract.Assert(m_leftSource != null); Contract.Assert(m_rightSource != null); if (m_outputEnumerator == null) { IEqualityComparer <Wrapper <TInputOutput> > wrapperComparer = new WrapperEqualityComparer <TInputOutput>(m_comparer); Dictionary <Wrapper <TInputOutput>, Pair <TInputOutput, ConcatKey <TLeftKey, TRightKey> > > union = new Dictionary <Wrapper <TInputOutput>, Pair <TInputOutput, ConcatKey <TLeftKey, TRightKey> > >(wrapperComparer); Pair <TInputOutput, NoKeyMemoizationRequired> elem = default(Pair <TInputOutput, NoKeyMemoizationRequired>); TLeftKey leftKey = default(TLeftKey); int i = 0; while (m_leftSource.MoveNext(ref elem, ref leftKey)) { if ((i++ & CancellationState.POLL_INTERVAL) == 0) { CancellationState.ThrowIfCanceled(m_cancellationToken); } ConcatKey <TLeftKey, TRightKey> key = ConcatKey <TLeftKey, TRightKey> .MakeLeft(m_leftOrdered?leftKey : default(TLeftKey)); Pair <TInputOutput, ConcatKey <TLeftKey, TRightKey> > oldEntry; Wrapper <TInputOutput> wrappedElem = new Wrapper <TInputOutput>(elem.First); if (!union.TryGetValue(wrappedElem, out oldEntry) || m_keyComparer.Compare(key, oldEntry.Second) < 0) { union[wrappedElem] = new Pair <TInputOutput, ConcatKey <TLeftKey, TRightKey> >(elem.First, key); } } TRightKey rightKey = default(TRightKey); while (m_rightSource.MoveNext(ref elem, ref rightKey)) { if ((i++ & CancellationState.POLL_INTERVAL) == 0) { CancellationState.ThrowIfCanceled(m_cancellationToken); } ConcatKey <TLeftKey, TRightKey> key = ConcatKey <TLeftKey, TRightKey> .MakeRight(m_rightOrdered?rightKey : default(TRightKey)); Pair <TInputOutput, ConcatKey <TLeftKey, TRightKey> > oldEntry; Wrapper <TInputOutput> wrappedElem = new Wrapper <TInputOutput>(elem.First); if (!union.TryGetValue(wrappedElem, out oldEntry) || m_keyComparer.Compare(key, oldEntry.Second) < 0) { union[wrappedElem] = new Pair <TInputOutput, ConcatKey <TLeftKey, TRightKey> >(elem.First, key);; } } m_outputEnumerator = union.GetEnumerator(); } if (m_outputEnumerator.MoveNext()) { Pair <TInputOutput, ConcatKey <TLeftKey, TRightKey> > current = m_outputEnumerator.Current.Value; currentElement = current.First; currentKey = current.Second; return(true); } return(false); }
//--------------------------------------------------------------------------------------- // MoveNext advances to the next element in the output. While the first data source has // elements, this consists of just advancing through it. After this, all partitions must // synchronize at a barrier and publish the maximum index N. Finally, all partitions can // move on to the second data source, adding N+1 to indices in order to get the correct // index offset. // internal override bool MoveNext([MaybeNullWhen(false), AllowNull] ref TSource currentElement, ref ConcatKey <TLeftKey, TRightKey> currentKey) { Debug.Assert(_firstSource != null); Debug.Assert(_secondSource != null); // If we are still enumerating the first source, fetch the next item. if (!_begunSecond) { // If elements remain, just return true and continue enumerating the left. TLeftKey leftKey = default(TLeftKey) !; if (_firstSource.MoveNext(ref currentElement !, ref leftKey)) { currentKey = ConcatKey <TLeftKey, TRightKey> .MakeLeft(leftKey); return(true); } _begunSecond = true; } // Now either move on to, or continue, enumerating the right data source. TRightKey rightKey = default(TRightKey) !; if (_secondSource.MoveNext(ref currentElement !, ref rightKey)) { currentKey = ConcatKey <TLeftKey, TRightKey> .MakeRight(rightKey); return(true); } return(false); }
//--------------------------------------------------------------------------------------- // Walks the two data sources, left and then right, to produce the union. // internal override bool MoveNext(ref TInputOutput currentElement, ref ConcatKey currentKey) { Debug.Assert(_leftSource != null); Debug.Assert(_rightSource != null); if (_outputEnumerator == null) { IEqualityComparer <Wrapper <TInputOutput> > wrapperComparer = new WrapperEqualityComparer <TInputOutput>(_comparer); Dictionary <Wrapper <TInputOutput>, Pair> union = new Dictionary <Wrapper <TInputOutput>, Pair>(wrapperComparer); Pair elem = new Pair(default(TInputOutput), default(NoKeyMemoizationRequired)); TLeftKey leftKey = default(TLeftKey); int i = 0; while (_leftSource.MoveNext(ref elem, ref leftKey)) { if ((i++ & CancellationState.POLL_INTERVAL) == 0) { CancellationState.ThrowIfCanceled(_cancellationToken); } ConcatKey key = ConcatKey.MakeLeft <TLeftKey, TRightKey>(_leftOrdered ? leftKey : default(TLeftKey)); Pair oldEntry; Wrapper <TInputOutput> wrappedElem = new Wrapper <TInputOutput>((TInputOutput)elem.First); if (!union.TryGetValue(wrappedElem, out oldEntry) || _keyComparer.Compare(key, (ConcatKey)oldEntry.Second) < 0) { union[wrappedElem] = new Pair(elem.First, key); } } TRightKey rightKey = default(TRightKey); while (_rightSource.MoveNext(ref elem, ref rightKey)) { if ((i++ & CancellationState.POLL_INTERVAL) == 0) { CancellationState.ThrowIfCanceled(_cancellationToken); } ConcatKey key = ConcatKey.MakeRight <TLeftKey, TRightKey>(_rightOrdered ? rightKey : default(TRightKey)); Pair oldEntry; Wrapper <TInputOutput> wrappedElem = new Wrapper <TInputOutput>((TInputOutput)elem.First); if (!union.TryGetValue(wrappedElem, out oldEntry) || _keyComparer.Compare(key, (ConcatKey)oldEntry.Second) < 0) { union[wrappedElem] = new Pair(elem.First, key);; } } _outputEnumerator = union.GetEnumerator(); } if (_outputEnumerator.MoveNext()) { Pair current = _outputEnumerator.Current.Value; currentElement = (TInputOutput)current.First; currentKey = (ConcatKey)current.Second; return(true); } return(false); }
//--------------------------------------------------------------------------------------- // Walks the two data sources, left and then right, to produce the union. // internal override bool MoveNext([MaybeNullWhen(false), AllowNull] ref TInputOutput currentElement, ref ConcatKey <TLeftKey, TRightKey> currentKey) { Debug.Assert(_leftSource != null); Debug.Assert(_rightSource != null); if (_outputEnumerator == null) { IEqualityComparer <Wrapper <TInputOutput> > wrapperComparer = new WrapperEqualityComparer <TInputOutput>(_comparer); Dictionary <Wrapper <TInputOutput>, Pair <TInputOutput, ConcatKey <TLeftKey, TRightKey> > > union = new Dictionary <Wrapper <TInputOutput>, Pair <TInputOutput, ConcatKey <TLeftKey, TRightKey> > >(wrapperComparer); Pair <TInputOutput, NoKeyMemoizationRequired> elem = default(Pair <TInputOutput, NoKeyMemoizationRequired>); TLeftKey leftKey = default(TLeftKey) !; int i = 0; while (_leftSource.MoveNext(ref elem, ref leftKey)) { if ((i++ & CancellationState.POLL_INTERVAL) == 0) { _cancellationToken.ThrowIfCancellationRequested(); } ; ConcatKey <TLeftKey, TRightKey> key = ConcatKey <TLeftKey, TRightKey> .MakeLeft(_leftOrdered?leftKey : default);