//---------------------------------------------------------------------------------------
            // Tallies up the min/max of the underlying data source, walking the entire thing the first
            // time MoveNext is called on this object.
            //

            protected override bool MoveNextCore(ref double currentElement)
            {
                // Based on the sign, do either a min or max reduction.
                QueryOperatorEnumerator <double, TKey> source = _source;
                TKey keyUnused = default(TKey) !;

                if (source.MoveNext(ref currentElement, ref keyUnused))
                {
                    int i = 0;
                    // We just scroll through the enumerator and find the min or max.
                    if (_sign == -1)
                    {
                        double elem = default(double);
                        while (source.MoveNext(ref elem, ref keyUnused))
                        {
                            if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                            {
                                _cancellationToken.ThrowIfCancellationRequested();
                            }
                            ;

                            if (elem < currentElement || double.IsNaN(elem))
                            {
                                currentElement = elem;
                            }
                        }
                    }
                    else
                    {
                        double elem = default(double);
                        while (source.MoveNext(ref elem, ref keyUnused))
                        {
                            if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                            {
                                _cancellationToken.ThrowIfCancellationRequested();
                            }
                            ;

                            if (elem > currentElement || double.IsNaN(currentElement))
                            {
                                currentElement = elem;
                            }
                        }
                    }

                    // The sum has been calculated. Now just return.
                    return(true);
                }

                return(false);
            }
            //---------------------------------------------------------------------------------------
            // This enumerates the entire input source to perform the search. If another peer
            // partition finds an answer before us, we will voluntarily return (propagating the
            // peer's result).
            //

            internal override bool MoveNext(ref bool currentElement, ref int currentKey)
            {
                Debug.Assert(_comparer != null);

                // Avoid enumerating if we've already found an answer.
                if (_resultFoundFlag.Value)
                {
                    return(false);
                }

                // We just scroll through the enumerator and accumulate the result.
                TInput element   = default(TInput);
                TKey   keyUnused = default(TKey);

                if (_source.MoveNext(ref element, ref keyUnused))
                {
                    currentElement = false;
                    currentKey     = _partitionIndex;

                    // Continue walking the data so long as we haven't found an item that satisfies
                    // the condition we are searching for.
                    int i = 0;
                    do
                    {
                        if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                        {
                            CancellationState.ThrowIfCanceled(_cancellationToken);
                        }

                        if (_resultFoundFlag.Value)
                        {
                            // If cancellation occurred, it's because a successful answer was found.
                            return(false);
                        }

                        if (_comparer.Equals(element, _searchValue))
                        {
                            // We have found an item that satisfies the search. Cancel other
                            // workers that are concurrently searching, and return.
                            _resultFoundFlag.Value = true;
                            currentElement         = true;
                            break;
                        }
                    }while (_source.MoveNext(ref element, ref keyUnused));

                    return(true);
                }

                return(false);
            }
            //---------------------------------------------------------------------------------------
            // Tallies up the min/max of the underlying data source, walking the entire thing the first
            // time MoveNext is called on this object.
            //

            protected override bool MoveNextCore(ref decimal?currentElement)
            {
                // Based on the sign, do either a min or max reduction.
                QueryOperatorEnumerator <decimal?, TKey> source = _source;
                TKey keyUnused = default(TKey);

                if (source.MoveNext(ref currentElement, ref keyUnused))
                {
                    int i = 0;
                    // We just scroll through the enumerator and find the min or max.
                    if (_sign == -1)
                    {
                        decimal?elem = default(decimal?);
                        while (source.MoveNext(ref elem, ref keyUnused))
                        {
                            if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                            {
                                CancellationState.ThrowIfCanceled(_cancellationToken);
                            }

                            if (currentElement == null || elem < currentElement)
                            {
                                currentElement = elem;
                            }
                        }
                    }
                    else
                    {
                        decimal?elem = default(decimal?);
                        while (source.MoveNext(ref elem, ref keyUnused))
                        {
                            if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                            {
                                CancellationState.ThrowIfCanceled(_cancellationToken);
                            }

                            if (currentElement == null || elem > currentElement)
                            {
                                currentElement = elem;
                            }
                        }
                    }

                    // The sum has been calculated. Now just return.
                    return(true);
                }

                return(false);
            }
Beispiel #4
0
            //-----------------------------------------------------------------------------------
            // Moves to the next matching element in the underlying data stream.
            //

            internal override bool MoveNext(ref TInputOutput currentElement, ref TKey currentKey)
            {
                Debug.Assert(_predicate != null, "expected a compiled operator");

                // Iterate through the input until we reach the end of the sequence or find
                // an element matching the predicate.

                if (_outputLoopCount == null)
                {
                    _outputLoopCount = new Shared <int>(0);
                }

                while (_source.MoveNext(ref currentElement, ref currentKey))
                {
                    if ((_outputLoopCount.Value++ & CancellationState.POLL_INTERVAL) == 0)
                    {
                        CancellationState.ThrowIfCanceled(_cancellationToken);
                    }

                    if (_predicate(currentElement))
                    {
                        return(true);
                    }
                }
                return(false);
            }
            //---------------------------------------------------------------------------------------
            // Enumerates the entire input until the element with the specified is found or another
            // partition has signaled that it found the element.
            //

            internal override bool MoveNext(ref TSource currentElement, ref int currentKey)
            {
                // Just walk the enumerator until we've found the element.
                int i = 0;

                while (_source.MoveNext(ref currentElement, ref currentKey))
                {
                    if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                    {
                        CancellationState.ThrowIfCanceled(_cancellationToken);
                    }

                    if (_resultFoundFlag.Value)
                    {
                        // Another partition found the element.
                        break;
                    }

                    if (currentKey == _index)
                    {
                        // We have found the element. Cancel other searches and return true.
                        _resultFoundFlag.Value = true;
                        return(true);
                    }
                }

                return(false);
            }
Beispiel #6
0
            //---------------------------------------------------------------------------------------
            // 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);
Beispiel #7
0
            //---------------------------------------------------------------------------------------
            // Just walks the entire data source upon its first invocation, performing the per-
            // element action for each element.
            //

            internal override bool MoveNext([MaybeNullWhen(false), AllowNull] ref TInput currentElement, ref int currentKey)
            {
                Debug.Assert(_elementAction != null, "expected a compiled operator");

                // We just scroll through the enumerator and execute the action. Because we execute
                // "in place", we actually never even produce a single value.

                // Cancellation testing must be performed here as full enumeration occurs within this method.
                // We only need to throw a simple exception here.. marshalling logic handled via QueryTaskGroupState.QueryEnd (called by ForAllSpoolingTask)
                TInput?element   = default(TInput);
                TKey?  keyUnused = default(TKey);
                int    i         = 0;

                while (_source.MoveNext(ref element, ref keyUnused))
                {
                    if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                    {
                        _cancellationToken.ThrowIfCancellationRequested();
                    }
                    ;
                    _elementAction(element);
                }

                return(false);
            }
Beispiel #8
0
            //---------------------------------------------------------------------------------------
            // 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(ref TSource currentElement, ref ConcatKey <TLeftKey, TRightKey> currentKey)
            {
                Contract.Assert(m_firstSource != null);
                Contract.Assert(m_secondSource != null);

                // If we are still enumerating the first source, fetch the next item.
                if (!m_begunSecond)
                {
                    // If elements remain, just return true and continue enumerating the left.
                    TLeftKey leftKey = default(TLeftKey);
                    if (m_firstSource.MoveNext(ref currentElement, ref leftKey))
                    {
                        currentKey = ConcatKey <TLeftKey, TRightKey> .MakeLeft(leftKey);

                        return(true);
                    }
                    m_begunSecond = true;
                }

                // Now either move on to, or continue, enumerating the right data source.
                TRightKey rightKey = default(TRightKey);

                if (m_secondSource.MoveNext(ref currentElement, ref rightKey))
                {
                    currentKey = ConcatKey <TLeftKey, TRightKey> .MakeRight(rightKey);

                    return(true);
                }

                return(false);
            }
        /// <summary>
        /// A variant of WrapEnumerable that accepts a QueryOperatorEnumerator{,} instead of an IEnumerable{}.
        /// The code duplication is necessary to avoid extra virtual method calls that would otherwise be needed to
        /// convert the QueryOperatorEnumerator{,} to an IEnumerator{}.
        /// </summary>
        internal static IEnumerable <TElement> WrapQueryEnumerator <TElement, TIgnoreKey>(QueryOperatorEnumerator <TElement, TIgnoreKey> source,
                                                                                          CancellationState cancellationState)
        {
            TElement   elem      = default(TElement);
            TIgnoreKey ignoreKey = default(TIgnoreKey);

            try
            {
                while (true)
                {
                    try
                    {
                        if (!source.MoveNext(ref elem, ref ignoreKey))
                        {
                            yield break;
                        }
                    }
                    catch (ThreadAbortException)
                    {
                        // Do not wrap ThreadAbortExceptions
                        throw;
                    }
                    catch (Exception ex)
                    {
                        ThrowOCEorAggregateException(ex, cancellationState);
                    }

                    yield return(elem);
                }
            }
            finally
            {
                source.Dispose();
            }
        }
Beispiel #10
0
        internal static IEnumerable <TElement> WrapQueryEnumerator <TElement, TIgnoreKey>(QueryOperatorEnumerator <TElement, TIgnoreKey> source, CancellationState cancellationState)
        {
            TElement   currentElement = default(TElement);
            TIgnoreKey currentKey     = default(TIgnoreKey);

            while (true)
            {
                try
                {
                    if (!source.MoveNext(ref currentElement, ref currentKey))
                    {
                        break;
                    }
                }
                catch (ThreadAbortException)
                {
                    throw;
                }
                catch (Exception exception)
                {
                    ThrowOCEorAggregateException(exception, cancellationState);
                }
                yield return(currentElement);
            }
        }
Beispiel #11
0
            //---------------------------------------------------------------------------------------
            // Tallies up the average of the underlying data source, walking the entire thing the first
            // time MoveNext is called on this object.
            //

            protected override bool MoveNextCore(ref Pair <decimal, long> currentElement)
            {
                // The temporary result contains the running sum and count, respectively.
                decimal sum   = 0.0m;
                long    count = 0;

                QueryOperatorEnumerator <decimal?, TKey> source = _source;
                decimal?current    = default(decimal?);
                TKey    currentKey = default(TKey) !;
                int     i          = 0;

                while (source.MoveNext(ref current, ref currentKey))
                {
                    if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                    {
                        _cancellationToken.ThrowIfCancellationRequested();
                    }
                    ;

                    if (current.HasValue)
                    {
                        checked
                        {
                            sum += current.GetValueOrDefault();
                            count++;
                        }
                    }
                }

                currentElement = new Pair <decimal, long>(sum, count);
                return(count > 0);
            }
            //---------------------------------------------------------------------------------------
            // Straightforward IEnumerator<T> methods.
            //

            internal override bool MoveNext(ref TSource currentElement, ref int currentKey)
            {
                Contract.Assert(m_source != null);

                if (m_alreadySearched)
                {
                    // If we've already searched, we will "fake out" the caller by returning an extra
                    // element at the end in the case that we've found more than one element.
                    if (m_yieldExtra)
                    {
                        m_yieldExtra   = false;
                        currentElement = default(TSource);
                        currentKey     = 0;
                        return(true);
                    }

                    return(false);
                }

                // Scan our input, looking for a match.
                bool    found     = false;
                TSource current   = default(TSource);
                TKey    keyUnused = default(TKey);

                while (m_source.MoveNext(ref current, ref keyUnused))
                {
                    // If the predicate is null or the current element satisfies it, we will remember
                    // it so that we can yield it later.  We then proceed with scanning the input
                    // in case there are multiple such elements.
                    if (m_predicate == null || m_predicate(current))
                    {
                        // Notify other partitions.
                        Interlocked.Increment(ref m_totalElementCount.Value);

                        currentElement = current;
                        currentKey     = 0;

                        if (found)
                        {
                            // Already found an element previously, we can exit.
                            m_yieldExtra = true;
                            break;
                        }
                        else
                        {
                            found = true;
                        }
                    }

                    // If we've already determined there is more than one matching element in the
                    // data source, we can exit right away.
                    if (Volatile.Read(ref m_totalElementCount.Value) > 1)
                    {
                        break;
                    }
                }
                m_alreadySearched = true;

                return(found);
            }
            //---------------------------------------------------------------------------------------
            // Tallies up the average of the underlying data source, walking the entire thing the first
            // time MoveNext is called on this object.
            //

            protected override bool MoveNextCore(ref Pair <long, long> currentElement)
            {
                // The temporary result contains the running sum and count, respectively.
                long sum   = 0;
                long count = 0;

                QueryOperatorEnumerator <int?, TKey> source = _source;
                int? current   = default(int?);
                TKey keyUnused = default(TKey);

                int i = 0;

                while (source.MoveNext(ref current, ref keyUnused))
                {
                    if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                    {
                        CancellationState.ThrowIfCanceled(_cancellationToken);
                    }

                    if (current.HasValue)
                    {
                        sum += current.GetValueOrDefault();
                        count++;
                    }
                }

                currentElement = new Pair <long, long>(sum, count);
                return(count > 0);
            }
Beispiel #14
0
            //---------------------------------------------------------------------------------------
            // Walks the two data sources, left and then right, to produce the distinct set
            //

            internal override bool MoveNext([MaybeNullWhen(false), AllowNull] ref TInputOutput currentElement, ref int currentKey)
            {
                Debug.Assert(_leftSource != null);
                Debug.Assert(_rightSource != null);

                // Build the set out of the left data source, if we haven't already.

                if (_hashLookup == null)
                {
                    _outputLoopCount = new Shared <int>(0);

                    _hashLookup = new HashSet <TInputOutput>(_comparer);

                    Pair <TInputOutput, NoKeyMemoizationRequired> rightElement = default(Pair <TInputOutput, NoKeyMemoizationRequired>);
                    int rightKeyUnused = default(int);

                    int i = 0;
                    while (_rightSource.MoveNext(ref rightElement, ref rightKeyUnused))
                    {
                        if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                        {
                            _cancellationToken.ThrowIfCancellationRequested();
                        }
                        ;

                        _hashLookup.Add(rightElement.First);
                    }
                }

                // Now iterate over the right data source, looking for matches.
                Pair <TInputOutput, NoKeyMemoizationRequired> leftElement = default(Pair <TInputOutput, NoKeyMemoizationRequired>);
                TLeftKey leftKeyUnused = default !;
Beispiel #15
0
        //-----------------------------------------------------------------------------------
        // This method is responsible for enumerating results and enqueueing them to
        // the output channel(s) as appropriate.  Each base class implements its own.
        //

        protected override void SpoolingWork()
        {
            // We just enumerate over the entire source data stream, placing each element
            // into the destination channel.
            TInputOutput current   = default(TInputOutput);
            TIgnoreKey   keyUnused = default(TIgnoreKey);

            QueryOperatorEnumerator <TInputOutput, TIgnoreKey> source = _source;
            AsynchronousChannel <TInputOutput> destination            = _destination;
            CancellationToken cancelToken = _groupState.CancellationState.MergedCancellationToken;

            while (source.MoveNext(ref current, ref keyUnused))
            {
                // If an abort has been requested, stop this worker immediately.
                if (cancelToken.IsCancellationRequested)
                {
                    break;
                }

                destination.Enqueue(current);
            }

            // Flush remaining data to the query consumer in preparation for channel shutdown.
            destination.FlushBuffers();
        }
Beispiel #16
0
            //---------------------------------------------------------------------------------------
            // Straightforward IEnumerator<T> methods.
            //

            internal override bool MoveNext(ref TSource currentElement, ref TKey currentKey)
            {
                // If the buffer has not been created, we will generate it lazily on demand.
                if (_buffer == null)
                {
                    _bufferIndex = new Shared <int>(0);
                    // Buffer all of our data.
                    _buffer = new List <Pair>();
                    TSource current = default(TSource);
                    TKey    key     = default(TKey);
                    int     i       = 0;
                    while (_source.MoveNext(ref current, ref key))
                    {
                        if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                        {
                            CancellationState.ThrowIfCanceled(_cancellationToken);
                        }

                        _buffer.Add(new Pair(current, key));
                        _bufferIndex.Value++;
                    }
                }

                // Continue yielding elements from our buffer.
                if (--_bufferIndex.Value >= 0)
                {
                    currentElement = (TSource)_buffer[_bufferIndex.Value].First;
                    currentKey     = (TKey)_buffer[_bufferIndex.Value].Second;
                    return(true);
                }

                return(false);
            }
            //---------------------------------------------------------------------------------------
            // Walks the single data source, skipping elements it has already seen.
            //

            internal override bool MoveNext(ref TInputOutput currentElement, ref int currentKey)
            {
                Debug.Assert(_source != null);
                Debug.Assert(_hashLookup != null);

                // Iterate over this set's elements until we find a unique element.
                TKey keyUnused = default(TKey);
                Pair <TInputOutput, NoKeyMemoizationRequired> current = default(Pair <TInputOutput, NoKeyMemoizationRequired>);

                if (_outputLoopCount == null)
                {
                    _outputLoopCount = new Shared <int>(0);
                }

                while (_source.MoveNext(ref current, ref keyUnused))
                {
                    if ((_outputLoopCount.Value++ & CancellationState.POLL_INTERVAL) == 0)
                    {
                        CancellationState.ThrowIfCanceled(_cancellationToken);
                    }

                    // We ensure we never return duplicates by tracking them in our set.
                    if (_hashLookup.Add(current.First))
                    {
#if DEBUG
                        currentKey = unchecked ((int)0xdeadbeef);
#endif
                        currentElement = current.First;
                        return(true);
                    }
                }

                return(false);
            }
            //---------------------------------------------------------------------------------------
            // Walks the two data sources, left and then right, to produce the intersection.
            //

            internal override bool MoveNext(ref TInputOutput currentElement, ref int currentKey)
            {
                Contract.Assert(m_leftSource != null);
                Contract.Assert(m_rightSource != null);

                // Build the set out of the right data source, if we haven't already.

                if (m_hashLookup == null)
                {
                    m_outputLoopCount = new Shared <int>(0);
                    // @TODO: @PERF: @BUG#594: different implementation of set operations. Consider a treap.
                    m_hashLookup = new Set <TInputOutput>(m_comparer);

                    Pair <TInputOutput, NoKeyMemoizationRequired> rightElement = default(Pair <TInputOutput, NoKeyMemoizationRequired>);
                    int rightKeyUnused = default(int);

                    int i = 0;
                    while (m_rightSource.MoveNext(ref rightElement, ref rightKeyUnused))
                    {
                        if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                        {
                            CancellationState.ThrowIfCanceled(m_cancellationToken);
                        }

                        m_hashLookup.Add(rightElement.First);
                    }
                }

                // Now iterate over the left data source, looking for matches.
                Pair <TInputOutput, NoKeyMemoizationRequired> leftElement = default(Pair <TInputOutput, NoKeyMemoizationRequired>);
                TLeftKey keyUnused = default(TLeftKey);

                while (m_leftSource.MoveNext(ref leftElement, ref keyUnused))
                {
                    if ((m_outputLoopCount.Value++ & CancellationState.POLL_INTERVAL) == 0)
                    {
                        CancellationState.ThrowIfCanceled(m_cancellationToken);
                    }

                    // If we found the element in our set, and if we haven't returned it yet,
                    // we can yield it to the caller. We also mark it so we know we've returned
                    // it once already and never will again.
                    if (m_hashLookup.Contains(leftElement.First))
                    {
                        // @TODO: @PERF: avoid the double lookup required to remove the element
                        //     we have already found in the hashtable.
                        m_hashLookup.Remove(leftElement.First);
                        currentElement = leftElement.First;
#if DEBUG
                        currentKey = unchecked ((int)0xdeadbeef);
#endif
                        return(true);
                    }
                }

                return(false);
            }
            //---------------------------------------------------------------------------------------
            // Walks the two data sources, left and then right, to produce the intersection.
            //

            internal override bool MoveNext([MaybeNullWhen(false), AllowNull] ref TInputOutput currentElement, ref int currentKey)
            {
                Debug.Assert(_leftSource != null);
                Debug.Assert(_rightSource != null);

                // Build the set out of the right data source, if we haven't already.

                if (_hashLookup == null)
                {
                    _outputLoopCount = new Shared <int>(0);
                    _hashLookup      = new Set <TInputOutput>(_comparer);

                    Pair <TInputOutput, NoKeyMemoizationRequired> rightElement = default(Pair <TInputOutput, NoKeyMemoizationRequired>);
                    int rightKeyUnused = default(int);

                    int i = 0;
                    while (_rightSource.MoveNext(ref rightElement, ref rightKeyUnused))
                    {
                        if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                        {
                            _cancellationToken.ThrowIfCancellationRequested();
                        }
                        ;

                        _hashLookup.Add(rightElement.First);
                    }
                }

                // Now iterate over the left data source, looking for matches.
                Pair <TInputOutput, NoKeyMemoizationRequired> leftElement = default(Pair <TInputOutput, NoKeyMemoizationRequired>);
                TLeftKey keyUnused = default(TLeftKey) !;

                while (_leftSource.MoveNext(ref leftElement, ref keyUnused))
                {
                    Debug.Assert(_outputLoopCount != null);
                    if ((_outputLoopCount.Value++ & CancellationState.POLL_INTERVAL) == 0)
                    {
                        _cancellationToken.ThrowIfCancellationRequested();
                    }
                    ;

                    // If we found the element in our set, and if we haven't returned it yet,
                    // we can yield it to the caller. We also mark it so we know we've returned
                    // it once already and never will again.
                    if (_hashLookup.Remove(leftElement.First))
                    {
                        currentElement = leftElement.First;
#if DEBUG
                        currentKey = unchecked ((int)0xdeadbeef);
#endif
                        return(true);
                    }
                }

                return(false);
            }
            protected override bool MoveNextCore(ref float currentElement)
            {
                QueryOperatorEnumerator <float, TKey> source = this.m_source;
                TKey currentKey = default(TKey);

                if (!source.MoveNext(ref currentElement, ref currentKey))
                {
                    return(false);
                }
                int num = 0;

                if (this.m_sign == -1)
                {
                    float num2 = 0f;
                    while (source.MoveNext(ref num2, ref currentKey))
                    {
                        if ((num++ & 0x3f) == 0)
                        {
                            CancellationState.ThrowIfCanceled(base.m_cancellationToken);
                        }
                        if ((num2 < currentElement) || float.IsNaN(num2))
                        {
                            currentElement = num2;
                        }
                    }
                }
                else
                {
                    float num3 = 0f;
                    while (source.MoveNext(ref num3, ref currentKey))
                    {
                        if ((num++ & 0x3f) == 0)
                        {
                            CancellationState.ThrowIfCanceled(base.m_cancellationToken);
                        }
                        if ((num3 > currentElement) || float.IsNaN(currentElement))
                        {
                            currentElement = num3;
                        }
                    }
                }
                return(true);
            }
            //---------------------------------------------------------------------------------------
            // Straightforward IEnumerator<T> methods.
            //

            internal override bool MoveNext(ref TSource currentElement, ref TKey currentKey)
            {
                Contract.Assert(m_source != null);

                bool moveNextResult = m_source.MoveNext(ref currentElement, ref currentKey);

                // There is special logic the first time this function is called.
                if (!m_lookedForEmpty)
                {
                    // Ensure we don't enter this loop again.
                    m_lookedForEmpty = true;

                    if (!moveNextResult)
                    {
                        if (m_partitionIndex == 0)
                        {
                            // If this is the 0th partition, we must wait for all others.  Note: we could
                            // actually do a wait-any here: if at least one other partition finds an element,
                            // there is strictly no need to wait.  But this would require extra coordination
                            // which may or may not be worth the trouble.
                            m_sharedLatch.Wait(m_cancelToken);
                            m_sharedLatch.Dispose();

                            // Now see if there were any other partitions with data.
                            if (m_sharedEmptyCount.Value == m_partitionCount - 1)
                            {
                                // No data, we will yield the default value.
                                currentElement = m_defaultValue;
                                currentKey     = default(TKey);
                                return(true);
                            }
                            else
                            {
                                // Another partition has data, we are done.
                                return(false);
                            }
                        }
                        else
                        {
                            // Not the 0th partition, we will increment the shared empty counter.
                            Interlocked.Increment(ref m_sharedEmptyCount.Value);
                        }
                    }

                    // Every partition (but the 0th) will signal the latch the first time.
                    if (m_partitionIndex != 0)
                    {
                        m_sharedLatch.Signal();
                    }
                }

                return(moveNextResult);
            }
Beispiel #22
0
        //-----------------------------------------------------------------------------------
        // This method is responsible for enumerating results and enqueueing them to
        // the output channel(s) as appropriate.  Each base class implements its own.
        //

        protected override void SpoolingWork()
        {
            // We just enumerate over the entire source data stream for effect.
            TInputOutput currentUnused = default(TInputOutput);
            TIgnoreKey   keyUnused     = default(TIgnoreKey);

            //Note: this only ever runs with a ForAll operator, and ForAllEnumerator performs cancellation checks
            while (_source.MoveNext(ref currentUnused, ref keyUnused))
            {
                ;
            }
        }
Beispiel #23
0
            //---------------------------------------------------------------------------------------
            // Walks the two data sources, left and then right, to produce the distinct set
            //

            internal override bool MoveNext(ref TInputOutput currentElement, ref int currentKey)
            {
                Contract.Assert(m_leftSource != null);
                Contract.Assert(m_rightSource != null);

                // Build the set out of the left data source, if we haven't already.

                if (m_hashLookup == null)
                {
                    m_outputLoopCount = new Shared <int>(0);

                    // @TODO: @PERF: @BUG#594: different implementation of set operations. Consider a treap.
                    m_hashLookup = new Set <TInputOutput>(m_comparer);

                    Pair <TInputOutput, NoKeyMemoizationRequired> rightElement = default(Pair <TInputOutput, NoKeyMemoizationRequired>);
                    int rightKeyUnused = default(int);

                    int i = 0;
                    while (m_rightSource.MoveNext(ref rightElement, ref rightKeyUnused))
                    {
                        if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                        {
                            CancellationState.ThrowIfCanceled(m_cancellationToken);
                        }

                        m_hashLookup.Add(rightElement.First);
                    }
                }

                // Now iterate over the right data source, looking for matches.
                Pair <TInputOutput, NoKeyMemoizationRequired> leftElement = default(Pair <TInputOutput, NoKeyMemoizationRequired>);
                TLeftKey leftKeyUnused = default(TLeftKey);

                while (m_leftSource.MoveNext(ref leftElement, ref leftKeyUnused))
                {
                    if ((m_outputLoopCount.Value++ & CancellationState.POLL_INTERVAL) == 0)
                    {
                        CancellationState.ThrowIfCanceled(m_cancellationToken);
                    }

                    if (m_hashLookup.Add(leftElement.First))
                    {
                        // This element has never been seen. Return it.
                        currentElement = leftElement.First;
#if DEBUG
                        currentKey = unchecked ((int)0xdeadbeef);
#endif
                        return(true);
                    }
                }

                return(false);
            }
Beispiel #24
0
            //---------------------------------------------------------------------------------------
            // Walks the two data sources, left and then right, to produce the distinct set
            //

            internal override bool MoveNext(ref TInputOutput currentElement, ref int currentKey)
            {
                Contract.Assert(_leftSource != null);
                Contract.Assert(_rightSource != null);

                // Build the set out of the left data source, if we haven't already.

                if (_hashLookup == null)
                {
                    _outputLoopCount = new Shared <int>(0);

                    _hashLookup = new Set <TInputOutput>(_comparer);

                    Pair rightElement   = new Pair(default(TInputOutput), default(NoKeyMemoizationRequired));
                    int  rightKeyUnused = default(int);

                    int i = 0;
                    while (_rightSource.MoveNext(ref rightElement, ref rightKeyUnused))
                    {
                        if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                        {
                            CancellationState.ThrowIfCanceled(_cancellationToken);
                        }

                        _hashLookup.Add((TInputOutput)rightElement.First);
                    }
                }

                // Now iterate over the right data source, looking for matches.
                Pair     leftElement   = new Pair(default(TInputOutput), default(NoKeyMemoizationRequired));
                TLeftKey leftKeyUnused = default(TLeftKey);

                while (_leftSource.MoveNext(ref leftElement, ref leftKeyUnused))
                {
                    if ((_outputLoopCount.Value++ & CancellationState.POLL_INTERVAL) == 0)
                    {
                        CancellationState.ThrowIfCanceled(_cancellationToken);
                    }

                    if (_hashLookup.Add((TInputOutput)leftElement.First))
                    {
                        // This element has never been seen. Return it.
                        currentElement = (TInputOutput)leftElement.First;
#if DEBUG
                        currentKey = unchecked ((int)0xdeadbeef);
#endif
                        return(true);
                    }
                }

                return(false);
            }
            //---------------------------------------------------------------------------------------
            // Straightforward IEnumerator<T> methods.
            //

            internal override bool MoveNext(ref TOutput currentElement, ref int currentKey)
            {
                // So long as the source has a next element, we have an element.
                TInput element = default(TInput);

                if (m_source.MoveNext(ref element, ref currentKey))
                {
                    Contract.Assert(m_selector != null, "expected a compiled selection function");
                    currentElement = m_selector(element, currentKey);
                    return(true);
                }

                return(false);
            }
Beispiel #26
0
            //---------------------------------------------------------------------------------------
            // Straightforward IEnumerator<T> methods.
            //

            internal override bool MoveNext(ref TOutput currentElement, ref TKey currentKey)
            {
                // So long as the source has a next element, we have an element.
                TInput element = default(TInput);

                if (_source.MoveNext(ref element, ref currentKey))
                {
                    Debug.Assert(_selector != null, "expected a compiled operator");
                    currentElement = _selector(element);
                    return(true);
                }

                return(false);
            }
Beispiel #27
0
        //---------------------------------------------------------------------------------------
        // Moves to the next element in the sorted output. When called for the first time, the
        // descendents in the sort's child tree are executed entirely, the results accumulated
        // in memory, and the data sorted.
        //

        internal override bool MoveNext(ref TInputOutput currentElement, ref TSortKey currentKey)
        {
            Debug.Assert(_source != null);

            TKey keyUnused = default(TKey);

            if (!_source.MoveNext(ref currentElement, ref keyUnused))
            {
                return(false);
            }

            currentKey = _keySelector(currentElement);
            return(true);
        }
            protected override bool MoveNextCore(ref long currentElement)
            {
                TSource local      = default(TSource);
                TKey    currentKey = default(TKey);
                QueryOperatorEnumerator <TSource, TKey> source = this.m_source;

                if (!source.MoveNext(ref local, ref currentKey))
                {
                    return(false);
                }
                long num  = 0L;
                int  num2 = 0;

                do
                {
                    if ((num2++ & 0x3f) == 0)
                    {
                        CancellationState.ThrowIfCanceled(base.m_cancellationToken);
                    }
                    num += 1L;
                }while (source.MoveNext(ref local, ref currentKey));
                currentElement = num;
                return(true);
            }
Beispiel #29
0
            protected override bool MoveNextCore(ref double currentElement)
            {
                float num        = 0f;
                TKey  currentKey = default(TKey);
                QueryOperatorEnumerator <float, TKey> source = this.m_source;

                if (!source.MoveNext(ref num, ref currentKey))
                {
                    return(false);
                }
                double num2 = 0.0;
                int    num3 = 0;

                do
                {
                    if ((num3++ & 0x3f) == 0)
                    {
                        CancellationState.ThrowIfCanceled(base.m_cancellationToken);
                    }
                    num2 += num;
                }while (source.MoveNext(ref num, ref currentKey));
                currentElement = num2;
                return(true);
            }
            protected override bool MoveNextCore(ref double?currentElement)
            {
                float?nullable   = null;
                TKey  currentKey = default(TKey);
                QueryOperatorEnumerator <float?, TKey> source = this.m_source;

                if (!source.MoveNext(ref nullable, ref currentKey))
                {
                    return(false);
                }
                float num  = 0f;
                int   num2 = 0;

                do
                {
                    if ((num2++ & 0x3f) == 0)
                    {
                        CancellationState.ThrowIfCanceled(base.m_cancellationToken);
                    }
                    num += nullable.GetValueOrDefault();
                }while (source.MoveNext(ref nullable, ref currentKey));
                currentElement = new double?((double)num);
                return(true);
            }